Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trim excessive zeros when printing integral compile-time reals #11075

Merged
merged 1 commit into from
Apr 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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