Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cast float to int without ANY conversion?

I am writing various types to a byte stream by manually casting and shifting values. I have found this to be more than three times faster than using BitConverter or BinaryWriter.

My problem is with floats. I need to cast them to ints in order to perform shift operations on them, but any cast to int will cause an implicit conversion with truncation, etc. I want the keep the exact binary representation the same. Is this possible?

eg. I want to be able to do similar to:

byte[] bytes = new byte[4];
float myFloat = 32.2;

//following won't compile as can't shift floats.
bytes [0] = (byte)myFloat;
bytes [1] = (byte)(myFloat >> 8);
bytes [2] = (byte)(myFloat >> 16);
bytes [3] = (byte)(myFloat >> 24);
like image 985
GazTheDestroyer Avatar asked Nov 07 '11 14:11

GazTheDestroyer


People also ask

Can you cast a float to an int?

Since a float is bigger than int, you can convert a float to an int by simply down-casting it e.g. (int) 4.0f will give you integer 4. By the way, you must remember that typecasting just get rid of anything after the decimal point, they don't perform any rounding or flooring operation on the value.

What will happen if you cast a float to an integer?

Casting a float to an integer truncates the value, so if you have 3.999998 , and you cast it to an integer , you get 3 .

Can you cast a float to an int in Java?

Java allows you to cast, or convert a variable of one type to another; in this case, cast a float to an int. This option removes all digits to the right of the decimal place. Another option is to use the Math. round method to round the value to the nearest integer.


1 Answers

The following does not require unsafe code and is proved to work (I used it for years across various .NET versions):

[StructLayout(LayoutKind.Explicit)]
public struct FloatAndUIntUnion
{
    [FieldOffset(0)]
    public uint  UInt32Bits;
    [FieldOffset(0)]
    public float FloatValue;
}


FloatAndUIntUnion f2i = default(FloatAndUIntUnion);
f2i.FloatValue = aFloat;    // write as float
uint i = f2i.UInt32Bits;    // read back as int

Note that the float→int direction can be simpler:

int i = aFloat.GetHashCode();

However, it is much more obscure because not documented (as per MSDN), although confirmed by this post. (That is, the behaviour was the same in 2006 as now in 2013, and I see no reason to change it in the future — but it may happen, and I'm unsure whether it would qualify as a backward-incompatible change or not.)

like image 189
robert4 Avatar answered Sep 22 '22 16:09

robert4