Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
March 02, 2017 Floating point rounding | ||||
---|---|---|---|---|
| ||||
I would expect that (1.0f + smallest float subnormal) > 1.0f when the Floating Point unit is set to Round Up. Here is some C++ code: #include <limits> #include <cstdio> #include <cfenv> int main(int, char**) { std::fesetround(FE_UPWARD); printf("%.32g\n", std::numeric_limits<float>::denorm_min() + 1.0f); return 0; } Execution on my machine yields: clang++ --std=c++11 test_denormal.cc && ./a.out 1.00000011920928955078125 Here is the same code in D: void main(string[] args) { import std.math; FloatingPointControl fpctrl; fpctrl.rounding = FloatingPointControl.roundUp; writefln("%.32g", float.min_normal + 1.0f); } Execution on my machine yields: dmd -run test_denormal.d 1 Did I miss something? |
March 02, 2017 Re: Floating point rounding | ||||
---|---|---|---|---|
| ||||
Posted in reply to Guillaume Chatelet | On Thursday, 2 March 2017 at 20:30:47 UTC, Guillaume Chatelet wrote:
> Here is the same code in D:
> void main(string[] args)
> {
> import std.math;
> FloatingPointControl fpctrl;
> fpctrl.rounding = FloatingPointControl.roundUp;
> writefln("%.32g", float.min_normal + 1.0f);
> }
>
> Execution on my machine yields:
> dmd -run test_denormal.d
> 1
>
> Did I miss something?
This example is closer to the C++ one:
void main(string[] args)
{
import core.stdc.fenv;
fesetround(FE_UPWARD);
writefln("%.32g", float.min_normal + 1.0f);
}
It still yields "1"
|
March 02, 2017 Re: Floating point rounding | ||||
---|---|---|---|---|
| ||||
Posted in reply to Guillaume Chatelet | On 03/02/2017 10:10 PM, Guillaume Chatelet wrote: > On Thursday, 2 March 2017 at 20:30:47 UTC, Guillaume Chatelet wrote: >> Here is the same code in D: >> void main(string[] args) >> { >> import std.math; >> FloatingPointControl fpctrl; >> fpctrl.rounding = FloatingPointControl.roundUp; >> writefln("%.32g", float.min_normal + 1.0f); >> } >> >> Execution on my machine yields: >> dmd -run test_denormal.d >> 1 >> >> Did I miss something? > > This example is closer to the C++ one: > > void main(string[] args) > { > import core.stdc.fenv; > fesetround(FE_UPWARD); > writefln("%.32g", float.min_normal + 1.0f); > } > > It still yields "1" This prints the same as the C++ version: ---- void main(string[] args) { import std.stdio; import core.stdc.fenv; fesetround(FE_UPWARD); float x = 1.0f; x += float.min_normal; writefln("%.32g", x); } ---- Soo, a bug/limitation of constant folding? With FloatingPointControl it still prints "1". Does FloatingPointControl.rounding do something different than fesetround? The example in the docs [1] only shows how it changes rint's behavior. [1] http://dlang.org/phobos/std_math.html#.FloatingPointControl |
March 02, 2017 Re: Floating point rounding | ||||
---|---|---|---|---|
| ||||
Posted in reply to ag0aep6g | On Thursday, 2 March 2017 at 21:34:56 UTC, ag0aep6g wrote: > On 03/02/2017 10:10 PM, Guillaume Chatelet wrote: >> On Thursday, 2 March 2017 at 20:30:47 UTC, Guillaume Chatelet wrote: >>> Here is the same code in D: >>> void main(string[] args) >>> { >>> import std.math; >>> FloatingPointControl fpctrl; >>> fpctrl.rounding = FloatingPointControl.roundUp; >>> writefln("%.32g", float.min_normal + 1.0f); >>> } >>> >>> Execution on my machine yields: >>> dmd -run test_denormal.d >>> 1 >>> >>> Did I miss something? >> >> This example is closer to the C++ one: >> >> void main(string[] args) >> { >> import core.stdc.fenv; >> fesetround(FE_UPWARD); >> writefln("%.32g", float.min_normal + 1.0f); >> } >> >> It still yields "1" > > This prints the same as the C++ version: > > ---- > void main(string[] args) > { > import std.stdio; > import core.stdc.fenv; > fesetround(FE_UPWARD); > float x = 1.0f; > x += float.min_normal; > writefln("%.32g", x); > } > ---- > > Soo, a bug/limitation of constant folding? > > With FloatingPointControl it still prints "1". Does FloatingPointControl.rounding do something different than fesetround? The example in the docs [1] only shows how it changes rint's behavior. > > > [1] http://dlang.org/phobos/std_math.html#.FloatingPointControl Thx for the investigation! Here is the code for FloatingPointControl https://github.com/dlang/phobos/blob/master/std/math.d#L4809 Other code (enableExceptions / disableExceptions) seems to have two code path depending on "version(X86_Any)", rounding doesn't. Maybe that's the bug? |
March 03, 2017 Re: Floating point rounding | ||||
---|---|---|---|---|
| ||||
Posted in reply to Guillaume Chatelet | On 03/02/2017 10:49 PM, Guillaume Chatelet wrote: > Thx for the investigation! > Here is the code for FloatingPointControl > https://github.com/dlang/phobos/blob/master/std/math.d#L4809 > > Other code (enableExceptions / disableExceptions) seems to have two code > path depending on "version(X86_Any)", rounding doesn't. > > Maybe that's the bug? I don't think that's it. But I think I've figured out what's wrong: dmd generates SSE instructions for floating point math. FloatingPointControl only minds the control register for the FPU. But SSE instructions are not affected by that. SSE has a separate control register: MXCSR. Too see that dmd generates SSE instructions: echo 'void main() { float x; x += 0.1f; }' > test.d && \ dmd -c test.d && \ objdump -d -Mintel -j.text._Dmain test.o Note the instructions movss and addss, and the xmm registers. To affect those instructions, FloatinPointControl.setsetControlState [1] must use ldmxcsr in addition to or instead of fldcw. This should be a pretty obvious bug. Rounding (and floating point exceptions?) must not be covered in the phobos tests at all. [1] https://github.com/dlang/phobos/blob/750593738bcbe9577c3f5951b5b639392871f90e/std/math.d#L4906-L4933 |
March 04, 2017 Re: Floating point rounding | ||||
---|---|---|---|---|
| ||||
Posted in reply to ag0aep6g | On 03/03/2017 05:39 PM, ag0aep6g wrote: > dmd generates SSE instructions for floating point math. > FloatingPointControl only minds the control register for the FPU. But > SSE instructions are not affected by that. SSE has a separate control > register: MXCSR. I've filed an issue: https://issues.dlang.org/show_bug.cgi?id=17243 and am attempting to fix it: https://github.com/dlang/phobos/pull/5240 |
Copyright © 1999-2021 by the D Language Foundation