Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the IEEE 754 binary representation of a float in C#

Tags:

I have some single and double precision floats that I want to write to and read from a byte[]. Is there anything in .Net I can use to convert them to and from their 32 and 64 bit IEEE 754 representations?

like image 382
HasaniH Avatar asked Nov 22 '10 19:11

HasaniH


People also ask

How are floats represented in binary in C?

Floating point basics etc. The mantissa is usually represented in base b, as a binary fraction. So (in a very low-precision format), 1 would be 1.000*20, 2 would be 1.000*21, and 0.375 would be 1.100*2-2, where the first 1 after the decimal point counts as 1/2, the second as 1/4, etc.

How do you write a floating-point in C?

Float is a datatype which is used to represent the floating point numbers. It is a 32-bit IEEE 754 single precision floating point number ( 1-bit for the sign, 8-bit for exponent, 23*-bit for the value. It has 6 decimal digits of precision.

How many bits is a float in C?

float is a 32-bit IEEE 754 single precision Floating Point Number – 1 bit for the sign, 8 bits for the exponent, and 23* for the value. float has 7 decimal digits of precision.

How does the IEEE 754 standard represent floating-point numbers?

IEEE Standard 754 floating point is the most common representation today for real numbers on computers, including Intel-based PC's, Macs, and most Unix platforms. This is as simple as the name. 0 represents a positive number while 1 represents a negative number.


2 Answers

.NET Single and Double are already in IEEE-754 format. You can use BitConverter.ToSingle() and ToDouble() to convert byte[] to floating point, GetBytes() to go the other way around.

like image 165
Hans Passant Avatar answered Sep 30 '22 03:09

Hans Passant


Update for current .NET/C# using spans:

static void Main() {     Span<byte> data = stackalloc byte[20];     GetBytes(0, data, 0);     GetBytes(123.45F, data, 4);     GetBytes(123.45D, data, 8); }  static unsafe void GetBytes(float value, Span<byte> buffer, int offset)     => MemoryMarshal.Cast<byte, float>(buffer.Slice(offset))[0] = value; static unsafe void GetBytes(double value, Span<byte> buffer, int offset)     => MemoryMarshal.Cast<byte, double>(buffer.Slice(offset))[0] = value; 

If you don't want to allocate new arrays all the time (which is what GetBytes does), you can use unsafe code to write to a buffer directly:

static void Main() {     byte[] data = new byte[20];     GetBytes(0, data, 0);     GetBytes(123.45F, data, 4);     GetBytes(123.45D, data, 8); }  static unsafe void GetBytes(float value, byte[] buffer, int offset) {     fixed (byte* ptr = &buffer[offset])     {         float* typed = (float*)ptr;         *typed = value;     } } static unsafe void GetBytes(double value, byte[] buffer, int offset) {     fixed (byte* ptr = &buffer[offset])     {         double* typed = (double*)ptr;         *typed = value;     } } 
like image 43
Marc Gravell Avatar answered Sep 30 '22 02:09

Marc Gravell