1

Would it be any difference in the outcome of a comparison between trivially comparing two always-positive floats and comparing them but after reinterpreting their binary representation as unsigned integers?

In other words, given variables float x,y; that are known to be always positive or zero and knowing the ieee-754 standard for storing 32-bit floats, can I assume that this comparison:

float x,y;
...
if ( x < y ) {...}

is always equivalent to:

float x,y;
unsigned int uix, uiy;
...
uix = *(unsigned int*)&x;
uiy = *(unsigned int*)&y;

if ( uix < uiy ) {...}

?

user2464424
  • 1,536
  • 1
  • 14
  • 28
  • Certainly not. IEEE format stores mantissa,exponent. As soon as both floats have a different exponent comparing the mantissa makes no longer sense. – DrKoch Mar 17 '15 at 11:25
  • @DrKoch Isn't the storage order the other way around: sign->exponent->mantissa? – user2464424 Mar 17 '15 at 11:28
  • Yes the storage order is the other way round which means that the most significant bits are the exponent which is what you would want compared first. So in general it will work. i.e. a larger exponent means a larger number. – James Snook Mar 17 '15 at 11:36
  • 1
    I'm not sure if IEEE standardizes endianness (in relation to endianness of integer types) -- perhaps a conforming implementation could have, say, all the bits reversed, making `if(uix > uiy)` the equivalent. – mafso Mar 17 '15 at 11:57

2 Answers2

3

If x and y are both strictly positive, then this works (ignoring possibly undefined-behavior from the pointer casts and assuming that you used a union or memcpy to do the type punning instead, and assuming that you are not on one of the few bizarre platforms where the endianness of floating-point does not match that of integer types), because positive binary floating-point numbers have the same ordering as their representations.

If y could be negative zero, then this does not work, because 0.f < -0.f is false, but 0x00000000 < 0x80000000 is true.

If y could be NaN, then this does not work, because the representation of a NaN compares greater than the representation of any positive number, whereas x < NaN is always false.

And obviously it doesn't work if x or y is negative.

Stephen Canon
  • 103,815
  • 19
  • 183
  • 269
  • 1
    Yikes. Which platforms use different endians for ints and floats? – tmyklebu Mar 17 '15 at 13:25
  • @tmyklebu: anecdotally, some ancient ARM implementations stored double-precision values in *mixed-endian* (two 32-bit little-endian words, most significant first). Off the top of my head I don't know of a platform with different storage orders for int32 and float32, but it *is* allowed by the relevant standards (even if bonkers). – Stephen Canon Mar 17 '15 at 13:49
  • If you type pun to 2's complement signed integers, and flip the sign when both are negative, you can resolve the negative problem. In fact (and presumably by design) this is the IEEE754 (and C TS-1:2014) `totalorder` predicate. See http://stackoverflow.com/a/20154751/392585 – Simon Byrne Mar 18 '15 at 10:52
1

No, it's not equivalent for the case of signed 0.

float x = 0.0;
float y = -0.0;

http://ideone.com/V7IYwL

Henrik
  • 23,186
  • 6
  • 42
  • 92