www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - floating point verification using is?

reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
If I have 2 identical floating point values, how do I ensure they are  
binary equivalents of eachother?  I'm trying to write some unittest/assert  
code, and it's not exactly trivial.

I thought 'a is b' would work, but it just morphs into a == b, which isn't  
helpful.  Why doesn't 'is' just do a bit compare for floating points?

-Steve
Dec 18 2009
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:

 If I have 2 identical floating point values, how do I ensure they are  
 binary equivalents of eachother?

Try this inside std.math of Phobos2: bool isIdentical(real x, real y);
 I thought 'a is b' would work, but it just morphs into a == b, which isn't  
 helpful.  Why doesn't 'is' just do a bit compare for floating points?

"is" is used to compare references. Bye, bearophile
Dec 18 2009
next sibling parent grauzone <none example.net> writes:
bearophile wrote:
 Steven Schveighoffer:
 
 If I have 2 identical floating point values, how do I ensure they are  
 binary equivalents of eachother?

Try this inside std.math of Phobos2: bool isIdentical(real x, real y);
 I thought 'a is b' would work, but it just morphs into a == b, which isn't  
 helpful.  Why doesn't 'is' just do a bit compare for floating points?

"is" is used to compare references.

No. If you use it with structs, the type's opEquals is not called. "is" is used for a lot of things. I agree that is should do a bitwise comparison for floating points. That would be a nice fix for D2.
 Bye,
 bearophile

Dec 18 2009
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:
 float x;
 
 assert(isIdentical(x, float.init)); // fails
 
 This is what I'm trying to test.  It has to do with the fact that  
 float.init is a literal, and I think it's automatically converted to  
 real.init.

Try this: http://www.digitalmars.com/d/2.0/phobos/std_math.html#isNaN Bye, bearophile
Dec 18 2009
parent reply bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:
 That's great, but I'm trying to verify that my array building code  
 correctly appends T.init.  isNaN returns true no matter what the bit  
 representation of nan is.  I want to *specifically* compare bit  
 representations of floating point numbers to ensure the code I'm writing  
 is doing what I think it's doing.

I see :-) Let's try again (but next time please explain the full problem in your first post, and not a slice of it): import std.c.stdio: printf; bool isNanInit(T)(T f) if (is(T == double) || is(T == float)) { union FPInt { T f; static if (is(T == float)) uint u; static if (is(T == double)) ulong u; } static FPInt fnan, fx; fx.f = f; return fnan.u == fx.u; } void main() { printf("%d\n", isNanInit(2.5)); float x; printf("%d\n", isNanInit(x)); x = 2.5; printf("%d\n", isNanInit(x)); } Bye, bearophile
Dec 18 2009
parent bearophile <bearophileHUGS lycos.com> writes:
This may be better, I have not taken a look at the resulting asm yet:

import std.traits: isFloatingPoint;
import std.c.stdio: printf;

bool isInitNan(T)(T f) if (isFloatingPoint!T) {
    union FPInt {
        T f;
        ubyte[T.sizeof] a;
    }
    static FPInt fnan, fx;
    fx.f = f;
    return fnan.a == fx.a;
}

void main() {
    printf("%d\n", isInitNan(2.5));
    float x;
    printf("%d\n", isInitNan(x));
    x = 2.5;
    printf("%d\n", isInitNan(x));
}
Dec 18 2009
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:
 to me, is means "ignore semantic meaning, do a bitwise compare" regardless  
 of reference status.
 
 For example comparing 2 array structs using == will check that all the  
 data is the same, but using "is" makes it compare bitwise the structs  
 directly.
 
 I see no difference with floating points, except you can't get at the bits  
 easily.  The existence of isIdentical could be completely replaced by one  
 or two instructions generated by the compiler when it sees "float is  
 float".

You can try expressing this idea in the main D group. Bye, bearophile
Dec 18 2009
prev sibling next sibling parent div0 <div0 users.sourceforge.net> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Steven Schveighoffer wrote:
 If I have 2 identical floating point values, how do I ensure they are
 binary equivalents of eachother?  I'm trying to write some
 unittest/assert code, and it's not exactly trivial.
 
 I thought 'a is b' would work, but it just morphs into a == b, which
 isn't helpful.  Why doesn't 'is' just do a bit compare for floating points?
 
 -Steve

Just out of curiosity; how many cases are there where a == b and they have different bit patterns? I can only think of +-0. Otherwise you can only get that with denormalised floats; which you won't get on an x86 processor. - -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iD8DBQFLK86uT9LetA9XoXwRAvtsAKDDoX6EzXj+wOIgTVHDzkRF0vXGsgCdH6tX QLvFQxYyjIwk7Qxi13VyrCI= =M18X -----END PGP SIGNATURE-----
Dec 18 2009
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 18 Dec 2009 13:49:18 -0500, div0 <div0 users.sourceforge.net>  
wrote:

 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1

 Steven Schveighoffer wrote:
 If I have 2 identical floating point values, how do I ensure they are
 binary equivalents of eachother?  I'm trying to write some
 unittest/assert code, and it's not exactly trivial.

 I thought 'a is b' would work, but it just morphs into a == b, which
 isn't helpful.  Why doesn't 'is' just do a bit compare for floating  
 points?

 -Steve

Just out of curiosity; how many cases are there where a == b and they have different bit patterns? I can only think of +-0. Otherwise you can only get that with denormalised floats; which you won't get on an x86 processor.

nan is the specific one I was trying to test for. From my very hazy memory, I think there can even be multiple binary representations of nan, but I'm not sure. -Steve
Dec 18 2009
parent BCS <none anon.com> writes:
Hello Steven,

 From my very hazy memory, I think there can even be multiple binary
 representations of nan, but I'm not sure.
 
 -Steve
 

yes, IIRC NaNs can have a few bits of payload as well as there being signaling and non-signaling NaNs.
Dec 18 2009
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 18 Dec 2009 12:34:09 -0500, bearophile <bearophileHUGS lycos.com>  
wrote:

 Steven Schveighoffer:

 If I have 2 identical floating point values, how do I ensure they are
 binary equivalents of eachother?

Try this inside std.math of Phobos2: bool isIdentical(real x, real y);

Thanks, that seems to be what I want.
 I thought 'a is b' would work, but it just morphs into a == b, which  
 isn't
 helpful.  Why doesn't 'is' just do a bit compare for floating points?

"is" is used to compare references.

to me, is means "ignore semantic meaning, do a bitwise compare" regardless of reference status. For example comparing 2 array structs using == will check that all the data is the same, but using "is" makes it compare bitwise the structs directly. I see no difference with floating points, except you can't get at the bits easily. The existence of isIdentical could be completely replaced by one or two instructions generated by the compiler when it sees "float is float". -Steve
Dec 18 2009
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 18 Dec 2009 14:16:17 -0500, Steven Schveighoffer  
<schveiguy yahoo.com> wrote:

 On Fri, 18 Dec 2009 12:34:09 -0500, bearophile  
 <bearophileHUGS lycos.com> wrote:

 Steven Schveighoffer:

 If I have 2 identical floating point values, how do I ensure they are
 binary equivalents of eachother?

Try this inside std.math of Phobos2: bool isIdentical(real x, real y);

Thanks, that seems to be what I want.

Except it doesn't work with literals properly: float x; assert(isIdentical(x, float.init)); // fails This is what I'm trying to test. It has to do with the fact that float.init is a literal, and I think it's automatically converted to real.init. This code works: float x; float y; assert(isIdentical(x, y)); I'm going to file a bug on this, float is float should just work! -Steve
Dec 18 2009
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 18 Dec 2009 14:47:13 -0500, bearophile <bearophileHUGS lycos.com>  
wrote:

 Steven Schveighoffer:
 float x;

 assert(isIdentical(x, float.init)); // fails

 This is what I'm trying to test.  It has to do with the fact that
 float.init is a literal, and I think it's automatically converted to
 real.init.

Try this: http://www.digitalmars.com/d/2.0/phobos/std_math.html#isNaN

That's great, but I'm trying to verify that my array building code correctly appends T.init. isNaN returns true no matter what the bit representation of nan is. I want to *specifically* compare bit representations of floating point numbers to ensure the code I'm writing is doing what I think it's doing. It shouldn't be this complicated to do that. -Steve
Dec 18 2009