Skip to content

Commit

Permalink
Merge pull request #11075 from kinke/sprint
Browse files Browse the repository at this point in the history
Trim excessive zeros when printing integral compile-time reals
merged-on-behalf-of: Nicholas Wilson <[email protected]>
  • Loading branch information
dlang-bot authored Apr 29, 2020
2 parents 0e3d354 + cd678e4 commit 793635e
Show file tree
Hide file tree
Showing 15 changed files with 65 additions and 68 deletions.
37 changes: 25 additions & 12 deletions src/dmd/root/ctfloat.d
Original file line number Diff line number Diff line change
Expand Up @@ -192,26 +192,39 @@ extern (C++) struct CTFloat
{
version(CRuntime_Microsoft)
{
return cast(int)ld_sprint(str, fmt, longdouble_soft(x));
auto len = cast(int) ld_sprint(str, fmt, longdouble_soft(x));
}
else
{
if (real_t(cast(ulong)x) == x)
char[4] sfmt = "%Lg\0";
sfmt[2] = fmt;
auto len = sprintf(str, sfmt.ptr, x);
}

if (fmt != 'a' && fmt != 'A')
{
assert(fmt == 'g');

// 1 => 1.0 to distinguish from integers
bool needsFPSuffix = true;
foreach (char c; str[0 .. len])
{
// ((1.5 -> 1 -> 1.0) == 1.5) is false
// ((1.0 -> 1 -> 1.0) == 1.0) is true
// see http://en.cppreference.com/w/cpp/io/c/fprintf
char[5] sfmt = "%#Lg\0";
sfmt[3] = fmt;
return sprintf(str, sfmt.ptr, x);
// str might be `nan` or `inf`...
if (c != '-' && !(c >= '0' && c <= '9'))
{
needsFPSuffix = false;
break;
}
}
else

if (needsFPSuffix)
{
char[4] sfmt = "%Lg\0";
sfmt[2] = fmt;
return sprintf(str, sfmt.ptr, x);
str[len .. len+3] = ".0\0";
len += 2;
}
}

return len;
}

// Constant real values 0, 1, -1 and 0.5.
Expand Down
7 changes: 0 additions & 7 deletions src/dmd/root/longdouble.d
Original file line number Diff line number Diff line change
Expand Up @@ -746,13 +746,6 @@ size_t ld_sprint(char* str, int fmt, longdouble_soft x) @system
// fmt is 'a','A','f' or 'g'
if(fmt != 'a' && fmt != 'A')
{
if (longdouble_soft(ld_readull(&x)) == x)
{ // ((1.5 -> 1 -> 1.0) == 1.5) is false
// ((1.0 -> 1 -> 1.0) == 1.0) is true
// see http://en.cppreference.com/w/cpp/io/c/fprintf
char[5] format = ['%', '#', 'L', cast(char)fmt, 0];
return sprintf(str, format.ptr, ld_read(&x));
}
char[3] format = ['%', cast(char)fmt, 0];
return sprintf(str, format.ptr, ld_read(&x));
}
Expand Down
10 changes: 5 additions & 5 deletions test/compilable/extra-files/header17125.di
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
void func1(real value = 103500L);
void func2(real value = 520199F);
void func3(real value = 970000);
void func4(real value = 102450F);
void func5(real value = 412502L);
void func1(real value = 103500.0L);
void func2(real value = 520199.0F);
void func3(real value = 970000.0);
void func4(real value = 102450.0F);
void func5(real value = 412502.0L);
int main();
2 changes: 1 addition & 1 deletion test/compilable/extra-files/header2.di
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ template templateVariableBar(T) if (is(T == int))
{
enum int templateVariableBar = T.stringof.length;
}
auto flit = 3 / 2.00000;
auto flit = 3 / 2.0;
void foo11217()(const int[] arr)
{
}
Expand Down
2 changes: 1 addition & 1 deletion test/compilable/extra-files/header2i.di
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ template templateVariableBar(T) if (is(T == int))
{
enum int templateVariableBar = T.stringof.length;
}
auto flit = 3 / 2.00000;
auto flit = 3 / 2.0;
void foo11217()(const int[] arr)
{
}
Expand Down
16 changes: 8 additions & 8 deletions test/compilable/test5227.d
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ log2()
log10()
0.740363L
round()
6.00000L
6.0L
floor()
5.00000F
5.00000
5.00000L
5.0F
5.0
5.0L
ceil()
6.00000F
6.00000
6.00000L
6.0F
6.0
6.0L
trunc()
5.00000L
5.0L
exp()
244.692L
expm1()
Expand Down
13 changes: 2 additions & 11 deletions test/dub_package/frontend_file.d
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,12 @@ void main()
t.module_.fullSemantic;
auto generated = t.module_.prettyPrint.toUnixLineEndings();

// For some reason the floating point number in the pretty printed code is
// different on Windows and on Posix. It might be due to different C
// standard libraries that are most likely used to convert the floating
// point number to a string.
version (Windows)
enum accumulator = "0.000000";
else
enum accumulator = "0.00000";

enum expected =q{module foo;
import object;
double average(int[] array)
{
immutable immutable(uint) initialLength = array.length;
double accumulator = %s;
double accumulator = 0.0;
for (; array.length;)
{
{
Expand All @@ -69,7 +60,7 @@ double average(int[] array)
}
return accumulator / cast(double)initialLength;
}
}.format(accumulator);
};

assert(generated.canFind(expected));
}
Expand Down
20 changes: 10 additions & 10 deletions test/fail_compilation/chkformat.d
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ fail_compilation/chkformat.d(101): Deprecation: precision argument `1L` for form
fail_compilation/chkformat.d(101): Deprecation: argument `2L` for format specification `"%*.*d"` must be `int`, not `long`
fail_compilation/chkformat.d(104): Deprecation: argument `4` for format specification `"%lld"` must be `long`, not `int`
fail_compilation/chkformat.d(105): Deprecation: argument `5` for format specification `"%jd"` must be `core.stdc.stdint.intmax_t`, not `int`
fail_compilation/chkformat.d(106): Deprecation: argument `6.00000` for format specification `"%zd"` must be `size_t`, not `double`
fail_compilation/chkformat.d(107): Deprecation: argument `7.00000` for format specification `"%td"` must be `ptrdiff_t`, not `double`
fail_compilation/chkformat.d(108): Deprecation: argument `8.00000L` for format specification `"%g"` must be `double`, not `real`
fail_compilation/chkformat.d(109): Deprecation: argument `9.00000` for format specification `"%Lg"` must be `real`, not `double`
fail_compilation/chkformat.d(106): Deprecation: argument `6.0` for format specification `"%zd"` must be `size_t`, not `double`
fail_compilation/chkformat.d(107): Deprecation: argument `7.0` for format specification `"%td"` must be `ptrdiff_t`, not `double`
fail_compilation/chkformat.d(108): Deprecation: argument `8.0L` for format specification `"%g"` must be `double`, not `real`
fail_compilation/chkformat.d(109): Deprecation: argument `9.0` for format specification `"%Lg"` must be `real`, not `double`
fail_compilation/chkformat.d(110): Deprecation: argument `10` for format specification `"%p"` must be `void*`, not `int`
fail_compilation/chkformat.d(111): Deprecation: argument `& u` for format specification `"%n"` must be `int*`, not `uint*`
fail_compilation/chkformat.d(113): Deprecation: argument `& u` for format specification `"%lln"` must be `long*`, not `int*`
Expand All @@ -25,12 +25,12 @@ fail_compilation/chkformat.d(202): Deprecation: more format specifiers than 1 ar
fail_compilation/chkformat.d(203): Deprecation: argument `0L` for format specification `"%d"` must be `int*`, not `long`
fail_compilation/chkformat.d(204): Deprecation: argument `0L` for format specification `"%3u"` must be `uint*`, not `long`
fail_compilation/chkformat.d(205): Deprecation: argument `u` for format specification `"%200u"` must be `uint*`, not `uint`
fail_compilation/chkformat.d(206): Deprecation: argument `3.00000` for format specification `"%hhd"` must be `byte*`, not `double`
fail_compilation/chkformat.d(206): Deprecation: argument `3.0` for format specification `"%hhd"` must be `byte*`, not `double`
fail_compilation/chkformat.d(207): Deprecation: argument `4` for format specification `"%hd"` must be `short*`, not `int`
fail_compilation/chkformat.d(209): Deprecation: argument `4` for format specification `"%lld"` must be `long*`, not `int`
fail_compilation/chkformat.d(210): Deprecation: argument `5` for format specification `"%jd"` must be `core.stdc.stdint.intmax_t*`, not `int`
fail_compilation/chkformat.d(211): Deprecation: argument `6.00000` for format specification `"%zd"` must be `size_t*`, not `double`
fail_compilation/chkformat.d(212): Deprecation: argument `7.00000` for format specification `"%td"` must be `ptrdiff_t*`, not `double`
fail_compilation/chkformat.d(211): Deprecation: argument `6.0` for format specification `"%zd"` must be `size_t*`, not `double`
fail_compilation/chkformat.d(212): Deprecation: argument `7.0` for format specification `"%td"` must be `ptrdiff_t*`, not `double`
fail_compilation/chkformat.d(213): Deprecation: format specifier `"%Ld"` is invalid
fail_compilation/chkformat.d(214): Deprecation: argument `0` for format specification `"%u"` must be `uint*`, not `int`
fail_compilation/chkformat.d(215): Deprecation: argument `0` for format specification `"%hhu"` must be `ubyte*`, not `int`
Expand All @@ -39,9 +39,9 @@ fail_compilation/chkformat.d(218): Deprecation: argument `0` for format specific
fail_compilation/chkformat.d(219): Deprecation: argument `0` for format specification `"%ju"` must be `ulong*`, not `int`
fail_compilation/chkformat.d(220): Deprecation: argument `0` for format specification `"%zu"` must be `size_t*`, not `int`
fail_compilation/chkformat.d(221): Deprecation: argument `0` for format specification `"%tu"` must be `ptrdiff_t*`, not `int`
fail_compilation/chkformat.d(222): Deprecation: argument `8.00000L` for format specification `"%g"` must be `float*`, not `real`
fail_compilation/chkformat.d(223): Deprecation: argument `8.00000L` for format specification `"%lg"` must be `double*`, not `real`
fail_compilation/chkformat.d(224): Deprecation: argument `9.00000` for format specification `"%Lg"` must be `real*`, not `double`
fail_compilation/chkformat.d(222): Deprecation: argument `8.0L` for format specification `"%g"` must be `float*`, not `real`
fail_compilation/chkformat.d(223): Deprecation: argument `8.0L` for format specification `"%lg"` must be `double*`, not `real`
fail_compilation/chkformat.d(224): Deprecation: argument `9.0` for format specification `"%Lg"` must be `real*`, not `double`
fail_compilation/chkformat.d(225): Deprecation: argument `& u` for format specification `"%s"` must be `char*`, not `int*`
fail_compilation/chkformat.d(226): Deprecation: argument `& u` for format specification `"%ls"` must be `wchar_t*`, not `int*`
fail_compilation/chkformat.d(227): Deprecation: argument `v` for format specification `"%p"` must be `void**`, not `void*`
Expand Down
2 changes: 1 addition & 1 deletion test/fail_compilation/diag16499.d
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
TEST_OUTPUT:
---
fail_compilation/diag16499.d(22): Error: incompatible types for `(2) in (foo)`: `int` and `A`
fail_compilation/diag16499.d(24): Error: incompatible types for `(1.00000) in (bar)`: `double` and `B`
fail_compilation/diag16499.d(24): Error: incompatible types for `(1.0) in (bar)`: `double` and `B`
---
*/

Expand Down
2 changes: 1 addition & 1 deletion test/fail_compilation/diag8101b.d
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ fail_compilation/diag8101b.d(28): Error: none of the overloads of `foo` are call
fail_compilation/diag8101b.d(19): `diag8101b.S.foo(int _param_0)`
fail_compilation/diag8101b.d(20): `diag8101b.S.foo(int _param_0, int _param_1)`
fail_compilation/diag8101b.d(30): Error: function `diag8101b.S.bar(int _param_0)` is not callable using argument types `(double)`
fail_compilation/diag8101b.d(30): cannot pass argument `1.00000` of type `double` to parameter `int _param_0`
fail_compilation/diag8101b.d(30): cannot pass argument `1.0` of type `double` to parameter `int _param_0`
fail_compilation/diag8101b.d(33): Error: none of the overloads of `foo` are callable using a `const` object, candidates are:
fail_compilation/diag8101b.d(19): `diag8101b.S.foo(int _param_0)`
fail_compilation/diag8101b.d(20): `diag8101b.S.foo(int _param_0, int _param_1)`
Expand Down
8 changes: 4 additions & 4 deletions test/fail_compilation/diag9357.d
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*
TEST_OUTPUT:
---
fail_compilation/diag9357.d(14): Error: cannot implicitly convert expression `1.00000` of type `double` to `int`
fail_compilation/diag9357.d(15): Error: cannot implicitly convert expression `10.0000` of type `double` to `int`
fail_compilation/diag9357.d(16): Error: cannot implicitly convert expression `11.0000` of type `double` to `int`
fail_compilation/diag9357.d(17): Error: cannot implicitly convert expression `99.0000` of type `double` to `int`
fail_compilation/diag9357.d(14): Error: cannot implicitly convert expression `1.0` of type `double` to `int`
fail_compilation/diag9357.d(15): Error: cannot implicitly convert expression `10.0` of type `double` to `int`
fail_compilation/diag9357.d(16): Error: cannot implicitly convert expression `11.0` of type `double` to `int`
fail_compilation/diag9357.d(17): Error: cannot implicitly convert expression `99.0` of type `double` to `int`
fail_compilation/diag9357.d(18): Error: cannot implicitly convert expression `1.04858e+06L` of type `real` to `int`
fail_compilation/diag9357.d(19): Error: cannot implicitly convert expression `1.04858e+06L` of type `real` to `int`
---
Expand Down
2 changes: 1 addition & 1 deletion test/fail_compilation/fail14304.d
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ fail_compilation/fail14304.d(35): Error: cannot modify read-only constant `[1:1,
fail_compilation/fail14304.d(61): called from here: `modify14304(aae14304)`
fail_compilation/fail14304.d(41): Error: cannot modify read-only constant `[1, 2, 3]`
fail_compilation/fail14304.d(64): called from here: `modify14304(cast(const(int)[])index14304)`
fail_compilation/fail14304.d(47): Error: cannot modify read-only constant `[1.414, 1.732, 2.00000]`
fail_compilation/fail14304.d(47): Error: cannot modify read-only constant `[1.414, 1.732, 2.0]`
fail_compilation/fail14304.d(67): called from here: `modify14304(cast(const(double)[])slice14304)`
fail_compilation/fail14304.d(53): Error: cannot modify read-only string literal `"abc"`
fail_compilation/fail14304.d(70): called from here: `modify14304(cast(const(char)[])str14304)`
Expand Down
2 changes: 1 addition & 1 deletion test/fail_compilation/fail340.d
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
TEST_OUTPUT:
---
fail_compilation/fail340.d(18): Error: variable `fail340.w` of type struct `const(CopyTest)` uses `this(this)`, which is not allowed in static initialization
fail_compilation/fail340.d(19): while evaluating: `static assert(w.x == 55.0000)`
fail_compilation/fail340.d(19): while evaluating: `static assert(w.x == 55.0)`
---
*/

Expand Down
6 changes: 3 additions & 3 deletions test/fail_compilation/fail5435.d
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ cast(Enum5435)1
cast(Enum5435)2
fail_compilation/fail5435.d(38): Error: cannot implicitly convert expression `"foo"` of type `string` to `Enum5435`
fail_compilation/fail5435.d(38): while evaluating `pragma(msg, foo)`
fail_compilation/fail5435.d(38): Error: cannot implicitly convert expression `3.00000` of type `double` to `Enum5435`
fail_compilation/fail5435.d(38): Error: cannot implicitly convert expression `3.0` of type `double` to `Enum5435`
fail_compilation/fail5435.d(38): while evaluating `pragma(msg, foo)`
fail_compilation/fail5435.d(39): Error: cannot implicitly convert expression `cast(Enum5435)0` of type `Enum5435` to `string`
fail_compilation/fail5435.d(39): while evaluating `pragma(msg, foo)`
Expand All @@ -16,14 +16,14 @@ fail_compilation/fail5435.d(39): while evaluating `pragma(msg, foo)`
fail_compilation/fail5435.d(39): Error: cannot implicitly convert expression `cast(Enum5435)2` of type `Enum5435` to `string`
fail_compilation/fail5435.d(39): while evaluating `pragma(msg, foo)`
foo
fail_compilation/fail5435.d(39): Error: cannot implicitly convert expression `3.00000` of type `double` to `string`
fail_compilation/fail5435.d(39): Error: cannot implicitly convert expression `3.0` of type `double` to `string`
fail_compilation/fail5435.d(39): while evaluating `pragma(msg, foo)`
0
1
2
fail_compilation/fail5435.d(40): Error: cannot implicitly convert expression `"foo"` of type `string` to `int`
fail_compilation/fail5435.d(40): while evaluating `pragma(msg, foo)`
fail_compilation/fail5435.d(40): Error: cannot implicitly convert expression `3.00000` of type `double` to `int`
fail_compilation/fail5435.d(40): Error: cannot implicitly convert expression `3.0` of type `double` to `int`
fail_compilation/fail5435.d(40): while evaluating `pragma(msg, foo)`
---
*/
Expand Down
4 changes: 2 additions & 2 deletions test/fail_compilation/ice20042.d
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
DISABLED: freebsd32 linux32 osx32 win32
TEST_OUTPUT:
---
fail_compilation/ice20042.d(18): Error: slice operation `cast(__vector(float[4]))nanF = [1.00000F, 2.00000F, 3.00000F, 4.00000F][0..4]` cannot be evaluated at compile time
fail_compilation/ice20042.d(25): called from here: `Vec4(cast(__vector(float[4]))[nanF, nanF, nanF, nanF]).this([1.00000F, 2.00000F, 3.00000F, 4.00000F])`
fail_compilation/ice20042.d(18): Error: slice operation `cast(__vector(float[4]))nanF = [1.0F, 2.0F, 3.0F, 4.0F][0..4]` cannot be evaluated at compile time
fail_compilation/ice20042.d(25): called from here: `Vec4(cast(__vector(float[4]))[nanF, nanF, nanF, nanF]).this([1.0F, 2.0F, 3.0F, 4.0F])`
---
*/
void write(T...)(T t){}
Expand Down

0 comments on commit 793635e

Please sign in to comment.