diff --git a/src/dmd/root/ctfloat.d b/src/dmd/root/ctfloat.d index ee3072122440..d09c83ab5f38 100644 --- a/src/dmd/root/ctfloat.d +++ b/src/dmd/root/ctfloat.d @@ -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. diff --git a/src/dmd/root/longdouble.d b/src/dmd/root/longdouble.d index 0feb518f71da..8869b9e21260 100644 --- a/src/dmd/root/longdouble.d +++ b/src/dmd/root/longdouble.d @@ -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)); } diff --git a/test/compilable/extra-files/header17125.di b/test/compilable/extra-files/header17125.di index 3b68d19b56aa..343477d4255e 100644 --- a/test/compilable/extra-files/header17125.di +++ b/test/compilable/extra-files/header17125.di @@ -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(); diff --git a/test/compilable/extra-files/header2.di b/test/compilable/extra-files/header2.di index 9f469b51a55f..11e882c760bf 100644 --- a/test/compilable/extra-files/header2.di +++ b/test/compilable/extra-files/header2.di @@ -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) { } diff --git a/test/compilable/extra-files/header2i.di b/test/compilable/extra-files/header2i.di index a8a1db04a7d9..313495c1bc60 100644 --- a/test/compilable/extra-files/header2i.di +++ b/test/compilable/extra-files/header2i.di @@ -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) { } diff --git a/test/compilable/test5227.d b/test/compilable/test5227.d index cbc2a99eb080..9748db3a9559 100644 --- a/test/compilable/test5227.d +++ b/test/compilable/test5227.d @@ -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() diff --git a/test/dub_package/frontend_file.d b/test/dub_package/frontend_file.d index 41f3c6a106fe..952971602776 100755 --- a/test/dub_package/frontend_file.d +++ b/test/dub_package/frontend_file.d @@ -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;) { { @@ -69,7 +60,7 @@ double average(int[] array) } return accumulator / cast(double)initialLength; } -}.format(accumulator); +}; assert(generated.canFind(expected)); } diff --git a/test/fail_compilation/chkformat.d b/test/fail_compilation/chkformat.d index a9fb395e54ef..7451b3f506bf 100644 --- a/test/fail_compilation/chkformat.d +++ b/test/fail_compilation/chkformat.d @@ -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*` @@ -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` @@ -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*` diff --git a/test/fail_compilation/diag16499.d b/test/fail_compilation/diag16499.d index 28b50fa29404..63b4b3c52795 100644 --- a/test/fail_compilation/diag16499.d +++ b/test/fail_compilation/diag16499.d @@ -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` --- */ diff --git a/test/fail_compilation/diag8101b.d b/test/fail_compilation/diag8101b.d index f8e5cefd9b00..05a333264174 100644 --- a/test/fail_compilation/diag8101b.d +++ b/test/fail_compilation/diag8101b.d @@ -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)` diff --git a/test/fail_compilation/diag9357.d b/test/fail_compilation/diag9357.d index f26b1c4482e0..097c8dee2500 100644 --- a/test/fail_compilation/diag9357.d +++ b/test/fail_compilation/diag9357.d @@ -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` --- diff --git a/test/fail_compilation/fail14304.d b/test/fail_compilation/fail14304.d index 488802490a86..7c0015db246c 100644 --- a/test/fail_compilation/fail14304.d +++ b/test/fail_compilation/fail14304.d @@ -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)` diff --git a/test/fail_compilation/fail340.d b/test/fail_compilation/fail340.d index 83be09c57e48..3d83e6896ed8 100644 --- a/test/fail_compilation/fail340.d +++ b/test/fail_compilation/fail340.d @@ -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)` --- */ diff --git a/test/fail_compilation/fail5435.d b/test/fail_compilation/fail5435.d index 731e30b69857..5d1b6591268b 100644 --- a/test/fail_compilation/fail5435.d +++ b/test/fail_compilation/fail5435.d @@ -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)` @@ -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)` --- */ diff --git a/test/fail_compilation/ice20042.d b/test/fail_compilation/ice20042.d index 7ba9309c0772..7fc3313cdfd8 100644 --- a/test/fail_compilation/ice20042.d +++ b/test/fail_compilation/ice20042.d @@ -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){}