Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map a 32 bit float to a 32 bit integer

Tags:

Is there a way to map floats to ints or unsigned ints so that with the exception of NaN, order is preserved?

So if a and b are floats, and F is the mapping function,

a < b implies F(a) < F(b) and a == b implies F(a) == F(b)

like image 291
zounds Avatar asked May 05 '10 18:05

zounds


People also ask

Can any 32-bit integer be represented in a 32-bit float?

Yes. All N bit ints can be represented in a floating point representation that has at least N-1 mantissa bits (because of the implicit leading 1 bit that doesn't need to be stored) and an exponent that can store at least N, i.e. has log(N)+1 bits.

How do you create a 32-bit integer?

You can declare 8-, 16-, 32-, or 64-bit integer variables by using the __intN type specifier, where N is 8, 16, 32, or 64. The types __int8 , __int16 , and __int32 are synonyms for the ANSI types that have the same size, and are useful for writing portable code that behaves identically across multiple platforms.

What is a 32-bit integer?

A signed integer is a 32-bit datum that encodes an integer in the range [-2147483648 to 2147483647]. An unsigned integer is a 32-bit datum that encodes a nonnegative integer in the range [0 to 4294967295]. The signed integer is represented in twos complement notation.

What is float in 32-bit?

Single-precision floating-point format (sometimes called FP32 or float32) is a computer number format, usually occupying 32 bits in computer memory; it represents a wide dynamic range of numeric values by using a floating radix point.


1 Answers

Hm, just out of the DawsonCompare routine in Game Programming Gems 6, it's a normal bit-cast followed by a sign flip (since negative floats order opposite then negative integers). I'll borrow that idea.

You have:

// utility template <typename R, typename T> R& bit_cast(T& pX) {     return reinterpret_cast<R&>(pX); }  // int32_t defined in <boost/cstdint.hpp>.  boost::int32_t float_to_int_bits(float pX) {     boost::int32_t x = bit_cast<boost::int32_t>(pX);      if (x < 0)         x = 0x80000000 - x;      return x; } 

If you can guarantee your int is 32 bits, you can just use that.


Fun fact: The book goes on to use this (note, not with the exact code I present, since I stripped out the float-to-int part) to compare floating point values with tolerance:

bool DawsonCompare(float pX, float pY, int pDiff) {     int x = float_to_int_bits(pX);     int y = float_to_int_bits(pY);      int diff = x - y;     return abs(diff) < pDiff; } 

This compares floats as true if their integer representations are within a certain range. (He uses 1000 as a good default.) A branch-less version called the LomontCompare is presented with the same idea, but you have to buy the book for that. :)

like image 87
GManNickG Avatar answered Oct 15 '22 03:10

GManNickG