2

I've been writing a port of a networking library from Java and this is the last line of code I have yet to decipher and move on over. The line of code is as follows:

Float.floatToIntBits(Float);

Which returns an integer.

The code of floatToIntBits in Java

public static int floatToIntBits(float value) {
        int result = floatToRawIntBits(value);
        // Check for NaN based on values of bit fields, maximum
        // exponent and nonzero significand.
        if ( ((result & FloatConsts.EXP_BIT_MASK) ==
              FloatConsts.EXP_BIT_MASK) &&
             (result & FloatConsts.SIGNIF_BIT_MASK) != 0)
            result = 0x7fc00000;
        return result;
    }

I'm not nearly experienced enough with memory and hex values to port this over myself, not to mention the bit shifting that's all over the place that's been driving me absolutely mad.

Hobbyist
  • 15,888
  • 9
  • 46
  • 98
  • Not sure why you need such code... Doesn't C# have an equivalent of Java's `ByteBuffer` (which can define endianness) that you can use instead? Or `Data*Stream`? You don't do all endianness operations by hand, do you? – fge Oct 16 '14 at 01:06
  • @fge - I am converting a networking library over to C# which requires the use of the functions, as it encrypts and decrypts the data in it's own way. – Hobbyist Oct 16 '14 at 01:30
  • Does this answer your question? [Convert int bits to float bits](https://stackoverflow.com/questions/27237776/convert-int-bits-to-float-bits) – phuclv Jun 04 '22 at 03:51
  • [How to convert float to uint by float representation?](https://stackoverflow.com/q/21801213/995714), [Convert float to raw bits to int in C#](https://stackoverflow.com/q/30786704/995714), [c# how to convert float to int](https://stackoverflow.com/q/7173677/995714), [C# floating point to binary string and vice versa](https://stackoverflow.com/q/59704806/995714) – phuclv Jun 04 '22 at 04:55

2 Answers2

6

Take a look at the BitConverter class. For doubles it has methods DoubleToInt64Bits and Int64BitsToDouble. For floats you could do something like this:

float f = ...;
int i = BitConverter.ToInt32(BitConverter.GetBytes(f), 0);

Or changing endianness:

byte[] bytes = BitConverter.GetBytes(f);
Array.Reverse(bytes);
int i = BitConverter.ToInt32(bytes, 0);
Dmitry
  • 13,797
  • 6
  • 32
  • 48
  • Didn't work, the following results were provided `Float: 5.2109E-41` from sending the float value of `72.5f` through the network. – Hobbyist Oct 16 '14 at 01:35
  • 1
    I've tried to change the endianness and got the same result for `72.5f`: `5.210868E-41`. So the second option in my answer **should** work. – Dmitry Oct 16 '14 at 11:11
1

If you can compile with unsafe, this becomes trivial:

public static unsafe uint FloatToUInt32Bits(float f) {
    return *((uint*)&f);
}

Replace uint with int if you want to work with signed values, but I would say unsigned makes more sense. This is actually equivalent to Java's floatToRawIntBits(); floatToIntBits() is identical except that it always returns the same bitmask for all NaN values. If you want that functionality, you can just replicate that if statement from the Java version, but it's probably unnecesssary.

You'll need to switch on 'unsafe' support for your assembly, so it's up to you whether you want to go this route. It's not at all uncommon for high performance networking libraries to use unsafe code.

Mike Strobel
  • 25,075
  • 57
  • 69
  • Now to figure out how to make Unity3D Allow unsafe code, Thanks for the post. I would like to make sure that I understand it though.. From the little bit of game modification I've done with creating "hacks" I know that the `*` operator declares a the value of an address in memory, however I've never seen it nested quite like this; Do you mind explaining? – Hobbyist Oct 16 '14 at 02:40
  • It's a throwback to the C language, really. The `&` operator produces the storage location (memory address) of a variable, in this case a pointer to a float (`float*`). The cast tells the compiler "this is actually a pointer to an `uint` value (a `uint*`)". The `*` operator retrieves the value at the storage location described by the pointer. So, basically, you're telling the compiler to read an `uint` value from the memory location where `f` is stored. You're getting whatever integer happens to have the same bitwise representation of the float value. – Mike Strobel Oct 16 '14 at 06:07