Skip to content

Commit cd678e4

Browse files
committed
Trim excessive zeros when printing integral compile-time reals
1 parent 0e3d354 commit cd678e4

15 files changed

+65
-68
lines changed

src/dmd/root/ctfloat.d

+25-12
Original file line numberDiff line numberDiff line change
@@ -192,26 +192,39 @@ extern (C++) struct CTFloat
192192
{
193193
version(CRuntime_Microsoft)
194194
{
195-
return cast(int)ld_sprint(str, fmt, longdouble_soft(x));
195+
auto len = cast(int) ld_sprint(str, fmt, longdouble_soft(x));
196196
}
197197
else
198198
{
199-
if (real_t(cast(ulong)x) == x)
199+
char[4] sfmt = "%Lg\0";
200+
sfmt[2] = fmt;
201+
auto len = sprintf(str, sfmt.ptr, x);
202+
}
203+
204+
if (fmt != 'a' && fmt != 'A')
205+
{
206+
assert(fmt == 'g');
207+
208+
// 1 => 1.0 to distinguish from integers
209+
bool needsFPSuffix = true;
210+
foreach (char c; str[0 .. len])
200211
{
201-
// ((1.5 -> 1 -> 1.0) == 1.5) is false
202-
// ((1.0 -> 1 -> 1.0) == 1.0) is true
203-
// see http://en.cppreference.com/w/cpp/io/c/fprintf
204-
char[5] sfmt = "%#Lg\0";
205-
sfmt[3] = fmt;
206-
return sprintf(str, sfmt.ptr, x);
212+
// str might be `nan` or `inf`...
213+
if (c != '-' && !(c >= '0' && c <= '9'))
214+
{
215+
needsFPSuffix = false;
216+
break;
217+
}
207218
}
208-
else
219+
220+
if (needsFPSuffix)
209221
{
210-
char[4] sfmt = "%Lg\0";
211-
sfmt[2] = fmt;
212-
return sprintf(str, sfmt.ptr, x);
222+
str[len .. len+3] = ".0\0";
223+
len += 2;
213224
}
214225
}
226+
227+
return len;
215228
}
216229

217230
// Constant real values 0, 1, -1 and 0.5.

src/dmd/root/longdouble.d

-7
Original file line numberDiff line numberDiff line change
@@ -746,13 +746,6 @@ size_t ld_sprint(char* str, int fmt, longdouble_soft x) @system
746746
// fmt is 'a','A','f' or 'g'
747747
if(fmt != 'a' && fmt != 'A')
748748
{
749-
if (longdouble_soft(ld_readull(&x)) == x)
750-
{ // ((1.5 -> 1 -> 1.0) == 1.5) is false
751-
// ((1.0 -> 1 -> 1.0) == 1.0) is true
752-
// see http://en.cppreference.com/w/cpp/io/c/fprintf
753-
char[5] format = ['%', '#', 'L', cast(char)fmt, 0];
754-
return sprintf(str, format.ptr, ld_read(&x));
755-
}
756749
char[3] format = ['%', cast(char)fmt, 0];
757750
return sprintf(str, format.ptr, ld_read(&x));
758751
}
+5-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
void func1(real value = 103500L);
2-
void func2(real value = 520199F);
3-
void func3(real value = 970000);
4-
void func4(real value = 102450F);
5-
void func5(real value = 412502L);
1+
void func1(real value = 103500.0L);
2+
void func2(real value = 520199.0F);
3+
void func3(real value = 970000.0);
4+
void func4(real value = 102450.0F);
5+
void func5(real value = 412502.0L);
66
int main();

test/compilable/extra-files/header2.di

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ template templateVariableBar(T) if (is(T == int))
7474
{
7575
enum int templateVariableBar = T.stringof.length;
7676
}
77-
auto flit = 3 / 2.00000;
77+
auto flit = 3 / 2.0;
7878
void foo11217()(const int[] arr)
7979
{
8080
}

test/compilable/extra-files/header2i.di

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ template templateVariableBar(T) if (is(T == int))
8787
{
8888
enum int templateVariableBar = T.stringof.length;
8989
}
90-
auto flit = 3 / 2.00000;
90+
auto flit = 3 / 2.0;
9191
void foo11217()(const int[] arr)
9292
{
9393
}

test/compilable/test5227.d

+8-8
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@ log2()
1010
log10()
1111
0.740363L
1212
round()
13-
6.00000L
13+
6.0L
1414
floor()
15-
5.00000F
16-
5.00000
17-
5.00000L
15+
5.0F
16+
5.0
17+
5.0L
1818
ceil()
19-
6.00000F
20-
6.00000
21-
6.00000L
19+
6.0F
20+
6.0
21+
6.0L
2222
trunc()
23-
5.00000L
23+
5.0L
2424
exp()
2525
244.692L
2626
expm1()

test/dub_package/frontend_file.d

+2-11
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,12 @@ void main()
4545
t.module_.fullSemantic;
4646
auto generated = t.module_.prettyPrint.toUnixLineEndings();
4747

48-
// For some reason the floating point number in the pretty printed code is
49-
// different on Windows and on Posix. It might be due to different C
50-
// standard libraries that are most likely used to convert the floating
51-
// point number to a string.
52-
version (Windows)
53-
enum accumulator = "0.000000";
54-
else
55-
enum accumulator = "0.00000";
56-
5748
enum expected =q{module foo;
5849
import object;
5950
double average(int[] array)
6051
{
6152
immutable immutable(uint) initialLength = array.length;
62-
double accumulator = %s;
53+
double accumulator = 0.0;
6354
for (; array.length;)
6455
{
6556
{
@@ -69,7 +60,7 @@ double average(int[] array)
6960
}
7061
return accumulator / cast(double)initialLength;
7162
}
72-
}.format(accumulator);
63+
};
7364

7465
assert(generated.canFind(expected));
7566
}

test/fail_compilation/chkformat.d

+10-10
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ fail_compilation/chkformat.d(101): Deprecation: precision argument `1L` for form
77
fail_compilation/chkformat.d(101): Deprecation: argument `2L` for format specification `"%*.*d"` must be `int`, not `long`
88
fail_compilation/chkformat.d(104): Deprecation: argument `4` for format specification `"%lld"` must be `long`, not `int`
99
fail_compilation/chkformat.d(105): Deprecation: argument `5` for format specification `"%jd"` must be `core.stdc.stdint.intmax_t`, not `int`
10-
fail_compilation/chkformat.d(106): Deprecation: argument `6.00000` for format specification `"%zd"` must be `size_t`, not `double`
11-
fail_compilation/chkformat.d(107): Deprecation: argument `7.00000` for format specification `"%td"` must be `ptrdiff_t`, not `double`
12-
fail_compilation/chkformat.d(108): Deprecation: argument `8.00000L` for format specification `"%g"` must be `double`, not `real`
13-
fail_compilation/chkformat.d(109): Deprecation: argument `9.00000` for format specification `"%Lg"` must be `real`, not `double`
10+
fail_compilation/chkformat.d(106): Deprecation: argument `6.0` for format specification `"%zd"` must be `size_t`, not `double`
11+
fail_compilation/chkformat.d(107): Deprecation: argument `7.0` for format specification `"%td"` must be `ptrdiff_t`, not `double`
12+
fail_compilation/chkformat.d(108): Deprecation: argument `8.0L` for format specification `"%g"` must be `double`, not `real`
13+
fail_compilation/chkformat.d(109): Deprecation: argument `9.0` for format specification `"%Lg"` must be `real`, not `double`
1414
fail_compilation/chkformat.d(110): Deprecation: argument `10` for format specification `"%p"` must be `void*`, not `int`
1515
fail_compilation/chkformat.d(111): Deprecation: argument `& u` for format specification `"%n"` must be `int*`, not `uint*`
1616
fail_compilation/chkformat.d(113): Deprecation: argument `& u` for format specification `"%lln"` must be `long*`, not `int*`
@@ -25,12 +25,12 @@ fail_compilation/chkformat.d(202): Deprecation: more format specifiers than 1 ar
2525
fail_compilation/chkformat.d(203): Deprecation: argument `0L` for format specification `"%d"` must be `int*`, not `long`
2626
fail_compilation/chkformat.d(204): Deprecation: argument `0L` for format specification `"%3u"` must be `uint*`, not `long`
2727
fail_compilation/chkformat.d(205): Deprecation: argument `u` for format specification `"%200u"` must be `uint*`, not `uint`
28-
fail_compilation/chkformat.d(206): Deprecation: argument `3.00000` for format specification `"%hhd"` must be `byte*`, not `double`
28+
fail_compilation/chkformat.d(206): Deprecation: argument `3.0` for format specification `"%hhd"` must be `byte*`, not `double`
2929
fail_compilation/chkformat.d(207): Deprecation: argument `4` for format specification `"%hd"` must be `short*`, not `int`
3030
fail_compilation/chkformat.d(209): Deprecation: argument `4` for format specification `"%lld"` must be `long*`, not `int`
3131
fail_compilation/chkformat.d(210): Deprecation: argument `5` for format specification `"%jd"` must be `core.stdc.stdint.intmax_t*`, not `int`
32-
fail_compilation/chkformat.d(211): Deprecation: argument `6.00000` for format specification `"%zd"` must be `size_t*`, not `double`
33-
fail_compilation/chkformat.d(212): Deprecation: argument `7.00000` for format specification `"%td"` must be `ptrdiff_t*`, not `double`
32+
fail_compilation/chkformat.d(211): Deprecation: argument `6.0` for format specification `"%zd"` must be `size_t*`, not `double`
33+
fail_compilation/chkformat.d(212): Deprecation: argument `7.0` for format specification `"%td"` must be `ptrdiff_t*`, not `double`
3434
fail_compilation/chkformat.d(213): Deprecation: format specifier `"%Ld"` is invalid
3535
fail_compilation/chkformat.d(214): Deprecation: argument `0` for format specification `"%u"` must be `uint*`, not `int`
3636
fail_compilation/chkformat.d(215): Deprecation: argument `0` for format specification `"%hhu"` must be `ubyte*`, not `int`
@@ -39,9 +39,9 @@ fail_compilation/chkformat.d(218): Deprecation: argument `0` for format specific
3939
fail_compilation/chkformat.d(219): Deprecation: argument `0` for format specification `"%ju"` must be `ulong*`, not `int`
4040
fail_compilation/chkformat.d(220): Deprecation: argument `0` for format specification `"%zu"` must be `size_t*`, not `int`
4141
fail_compilation/chkformat.d(221): Deprecation: argument `0` for format specification `"%tu"` must be `ptrdiff_t*`, not `int`
42-
fail_compilation/chkformat.d(222): Deprecation: argument `8.00000L` for format specification `"%g"` must be `float*`, not `real`
43-
fail_compilation/chkformat.d(223): Deprecation: argument `8.00000L` for format specification `"%lg"` must be `double*`, not `real`
44-
fail_compilation/chkformat.d(224): Deprecation: argument `9.00000` for format specification `"%Lg"` must be `real*`, not `double`
42+
fail_compilation/chkformat.d(222): Deprecation: argument `8.0L` for format specification `"%g"` must be `float*`, not `real`
43+
fail_compilation/chkformat.d(223): Deprecation: argument `8.0L` for format specification `"%lg"` must be `double*`, not `real`
44+
fail_compilation/chkformat.d(224): Deprecation: argument `9.0` for format specification `"%Lg"` must be `real*`, not `double`
4545
fail_compilation/chkformat.d(225): Deprecation: argument `& u` for format specification `"%s"` must be `char*`, not `int*`
4646
fail_compilation/chkformat.d(226): Deprecation: argument `& u` for format specification `"%ls"` must be `wchar_t*`, not `int*`
4747
fail_compilation/chkformat.d(227): Deprecation: argument `v` for format specification `"%p"` must be `void**`, not `void*`

test/fail_compilation/diag16499.d

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
TEST_OUTPUT:
33
---
44
fail_compilation/diag16499.d(22): Error: incompatible types for `(2) in (foo)`: `int` and `A`
5-
fail_compilation/diag16499.d(24): Error: incompatible types for `(1.00000) in (bar)`: `double` and `B`
5+
fail_compilation/diag16499.d(24): Error: incompatible types for `(1.0) in (bar)`: `double` and `B`
66
---
77
*/
88

test/fail_compilation/diag8101b.d

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ fail_compilation/diag8101b.d(28): Error: none of the overloads of `foo` are call
55
fail_compilation/diag8101b.d(19): `diag8101b.S.foo(int _param_0)`
66
fail_compilation/diag8101b.d(20): `diag8101b.S.foo(int _param_0, int _param_1)`
77
fail_compilation/diag8101b.d(30): Error: function `diag8101b.S.bar(int _param_0)` is not callable using argument types `(double)`
8-
fail_compilation/diag8101b.d(30): cannot pass argument `1.00000` of type `double` to parameter `int _param_0`
8+
fail_compilation/diag8101b.d(30): cannot pass argument `1.0` of type `double` to parameter `int _param_0`
99
fail_compilation/diag8101b.d(33): Error: none of the overloads of `foo` are callable using a `const` object, candidates are:
1010
fail_compilation/diag8101b.d(19): `diag8101b.S.foo(int _param_0)`
1111
fail_compilation/diag8101b.d(20): `diag8101b.S.foo(int _param_0, int _param_1)`

test/fail_compilation/diag9357.d

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
/*
22
TEST_OUTPUT:
33
---
4-
fail_compilation/diag9357.d(14): Error: cannot implicitly convert expression `1.00000` of type `double` to `int`
5-
fail_compilation/diag9357.d(15): Error: cannot implicitly convert expression `10.0000` of type `double` to `int`
6-
fail_compilation/diag9357.d(16): Error: cannot implicitly convert expression `11.0000` of type `double` to `int`
7-
fail_compilation/diag9357.d(17): Error: cannot implicitly convert expression `99.0000` of type `double` to `int`
4+
fail_compilation/diag9357.d(14): Error: cannot implicitly convert expression `1.0` of type `double` to `int`
5+
fail_compilation/diag9357.d(15): Error: cannot implicitly convert expression `10.0` of type `double` to `int`
6+
fail_compilation/diag9357.d(16): Error: cannot implicitly convert expression `11.0` of type `double` to `int`
7+
fail_compilation/diag9357.d(17): Error: cannot implicitly convert expression `99.0` of type `double` to `int`
88
fail_compilation/diag9357.d(18): Error: cannot implicitly convert expression `1.04858e+06L` of type `real` to `int`
99
fail_compilation/diag9357.d(19): Error: cannot implicitly convert expression `1.04858e+06L` of type `real` to `int`
1010
---

test/fail_compilation/fail14304.d

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ fail_compilation/fail14304.d(35): Error: cannot modify read-only constant `[1:1,
77
fail_compilation/fail14304.d(61): called from here: `modify14304(aae14304)`
88
fail_compilation/fail14304.d(41): Error: cannot modify read-only constant `[1, 2, 3]`
99
fail_compilation/fail14304.d(64): called from here: `modify14304(cast(const(int)[])index14304)`
10-
fail_compilation/fail14304.d(47): Error: cannot modify read-only constant `[1.414, 1.732, 2.00000]`
10+
fail_compilation/fail14304.d(47): Error: cannot modify read-only constant `[1.414, 1.732, 2.0]`
1111
fail_compilation/fail14304.d(67): called from here: `modify14304(cast(const(double)[])slice14304)`
1212
fail_compilation/fail14304.d(53): Error: cannot modify read-only string literal `"abc"`
1313
fail_compilation/fail14304.d(70): called from here: `modify14304(cast(const(char)[])str14304)`

test/fail_compilation/fail340.d

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
TEST_OUTPUT:
33
---
44
fail_compilation/fail340.d(18): Error: variable `fail340.w` of type struct `const(CopyTest)` uses `this(this)`, which is not allowed in static initialization
5-
fail_compilation/fail340.d(19): while evaluating: `static assert(w.x == 55.0000)`
5+
fail_compilation/fail340.d(19): while evaluating: `static assert(w.x == 55.0)`
66
---
77
*/
88

test/fail_compilation/fail5435.d

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ cast(Enum5435)1
77
cast(Enum5435)2
88
fail_compilation/fail5435.d(38): Error: cannot implicitly convert expression `"foo"` of type `string` to `Enum5435`
99
fail_compilation/fail5435.d(38): while evaluating `pragma(msg, foo)`
10-
fail_compilation/fail5435.d(38): Error: cannot implicitly convert expression `3.00000` of type `double` to `Enum5435`
10+
fail_compilation/fail5435.d(38): Error: cannot implicitly convert expression `3.0` of type `double` to `Enum5435`
1111
fail_compilation/fail5435.d(38): while evaluating `pragma(msg, foo)`
1212
fail_compilation/fail5435.d(39): Error: cannot implicitly convert expression `cast(Enum5435)0` of type `Enum5435` to `string`
1313
fail_compilation/fail5435.d(39): while evaluating `pragma(msg, foo)`
@@ -16,14 +16,14 @@ fail_compilation/fail5435.d(39): while evaluating `pragma(msg, foo)`
1616
fail_compilation/fail5435.d(39): Error: cannot implicitly convert expression `cast(Enum5435)2` of type `Enum5435` to `string`
1717
fail_compilation/fail5435.d(39): while evaluating `pragma(msg, foo)`
1818
foo
19-
fail_compilation/fail5435.d(39): Error: cannot implicitly convert expression `3.00000` of type `double` to `string`
19+
fail_compilation/fail5435.d(39): Error: cannot implicitly convert expression `3.0` of type `double` to `string`
2020
fail_compilation/fail5435.d(39): while evaluating `pragma(msg, foo)`
2121
0
2222
1
2323
2
2424
fail_compilation/fail5435.d(40): Error: cannot implicitly convert expression `"foo"` of type `string` to `int`
2525
fail_compilation/fail5435.d(40): while evaluating `pragma(msg, foo)`
26-
fail_compilation/fail5435.d(40): Error: cannot implicitly convert expression `3.00000` of type `double` to `int`
26+
fail_compilation/fail5435.d(40): Error: cannot implicitly convert expression `3.0` of type `double` to `int`
2727
fail_compilation/fail5435.d(40): while evaluating `pragma(msg, foo)`
2828
---
2929
*/

test/fail_compilation/ice20042.d

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
DISABLED: freebsd32 linux32 osx32 win32
33
TEST_OUTPUT:
44
---
5-
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
6-
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])`
5+
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
6+
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])`
77
---
88
*/
99
void write(T...)(T t){}

0 commit comments

Comments
 (0)