digitalmars.D.learn - Three floating point questions
- bearophile (41/41) Aug 25 2010 This program prints (dmd 2.048):
- Don (8/54) Aug 25 2010 You mean, because it's a negative nan?
- bearophile (9/17) Aug 25 2010 Yes, I mean that. Is a negative nan a meaningful concept? Is it a true n...
- Don (18/32) Aug 26 2010 It's the way signalling nans work. _Any_ use of them raises a floating
This program prints (dmd 2.048): 7ff4000000000000 7ffc000000000000 import std.stdio: writeln, writefln; import std.string: format; void main() { string toHex(T)(T x) { string result; ubyte* ptr = cast(ubyte*)&x; foreach (i; 0 .. T.sizeof) result = format("%02x", ptr[i]) ~ result; return result; } writeln(toHex(double.init)); writefln("%x", cast(ulong)double.init); } Do you know what cast(ulong) is doing here? --------------------------- This program prints (dmd 2.048):: -nan import std.stdio: writeln; void main() { writeln(0.0 / 0.0); } Is it a bug of writeln? --------------------------- Do you know why this isn't raising runtime errors? import std.math: FloatingPointControl; import std.c.stdlib: atof; void main() { double d3 = atof("3.0"); double x; // nan FloatingPointControl fpc; fpc.enableExceptions(FloatingPointControl.severeExceptions); double r = x * d3; } Bye, bearophile
Aug 25 2010
bearophile wrote:This program prints (dmd 2.048): 7ff4000000000000 7ffc000000000000 import std.stdio: writeln, writefln; import std.string: format; void main() { string toHex(T)(T x) { string result; ubyte* ptr = cast(ubyte*)&x; foreach (i; 0 .. T.sizeof) result = format("%02x", ptr[i]) ~ result; return result; } writeln(toHex(double.init)); writefln("%x", cast(ulong)double.init); } Do you know what cast(ulong) is doing here?Turning it from a signalling nan to a quiet nan.--------------------------- This program prints (dmd 2.048):: -nan import std.stdio: writeln; void main() { writeln(0.0 / 0.0); } Is it a bug of writeln?You mean, because it's a negative nan?--------------------------- Do you know why this isn't raising runtime errors? import std.math: FloatingPointControl; import std.c.stdlib: atof; void main() { double d3 = atof("3.0"); double x; // nan FloatingPointControl fpc; fpc.enableExceptions(FloatingPointControl.severeExceptions); double r = x * d3; }That's a known bug in the backend, which I still haven't fixed. The signalling nans get triggered in the 'double x; ' line. This happens because there's a difference in the way AMD and Intel deal with signalling nans, which is completely unpublicised. So my initial testing was inadequate.
Aug 25 2010
Don:I really really didn't know this. Is this written somewhere in the D docs? :-)Do you know what cast(ulong) is doing here?Turning it from a signalling nan to a quiet nan.You mean, because it's a negative nan?Yes, I mean that. Is a negative nan a meaningful concept? Is it a true negative nan coming from the division of two positive values, or it's just a bug of writeln, or is it something completely different?The signalling nans get triggered in the 'double x; ' line.(You are often two steps forward compared to my thought patterns, so please be patient with me) In this program the FP register is modified after that definition line, so I don't expect 'double x; ' to trigger an hardware exception. But the 'double r = x * d3;' line computes the product of a signaling nan and a normal double, so this is an operation that has to produce an error, I think.This happens because there's a difference in the way AMD and Intel deal with signalling nans, which is completely unpublicised. So my initial testing was inadequate.I see. If not even official CPU specs show such data, then not being right in the first (and second) implementation is forgiveable, I presume :o) Bye and thank you, bearophile
Aug 25 2010
bearophile wrote:Don:It's the way signalling nans work. _Any_ use of them raises a floating point exception, then turns them into a quiet NaN.I really really didn't know this. Is this written somewhere in the D docs? :-)Do you know what cast(ulong) is doing here?Turning it from a signalling nan to a quiet nan.It's part of the payload of the nan. Is it a true negative nan coming from the division of two positive values, or it's just a bug of writeln, or is it something completely different?You mean, because it's a negative nan?Yes, I mean that. Is a negative nan a meaningful concept?Unfortunately the way the backend deals with it at present is to do: double x; x = double.init; which is wrong because it involves an assignment, which may or may not trigger a floating point exception, depending on your cpu*. If it triggers one, then x contains a quiet nan, instead of a signalling one! So the signalling nan idea doesn't quite work yet. * it actually is documented in Intel/AMD docs for the FLD and FSTP instructions, but you have to read it _very_ carefully to notice. As far as I can tell, nobody has noticed the difference before. I only discovered it through experiment.The signalling nans get triggered in the 'double x; ' line.(You are often two steps forward compared to my thought patterns, so please be patient with me) In this program the FP register is modified after that definition line, so I don't expect 'double x; ' to trigger an hardware exception.
Aug 26 2010