0

I have my union setup to read a 32 bit float value which is 32.0800018310 (binary = 100000.0001010001111011).

Now I want to display the contents of the float using the integer array which is 12 bytes (8 bits per byte).

However I get the following output:

Display:
236 
81 
0 
66 

Shouldn't:

  • data_to_send[0] return the first 8 bits of the float, which is 01111011 (decimal = 123)
  • data_to_send[1] return the next 8 bits of the float which is 00010100 (decimal = 20)
  • data_to_send[2] return the next 8 bits of the float which is 100000. (decimal = 32)
  • data_to_send[3] return the next 8 bits of the float which is 0. (decimal = 0)

Also what happens to the . in the number? How do you display that?

union
{
  uint8_t  data_to_send[12];
  float    float_value;
} union_var;

union_var.float_value =  32.0800018310 

//display array
 USB.print("Display: ");
USB.printf("%d \n", union_var.data_to_send[0]);
USB.printf("%d \n", union_var.data_to_send[1]);
USB.printf("%d \n", union_var.data_to_send[2]);
USB.printf("%d \n", union_var.data_to_send[3]);
user3386109
  • 34,287
  • 7
  • 49
  • 68
solutery7
  • 21
  • 4

4 Answers4

3

How float values are stored depends on the architecture of your machine.

Nowadays, they are almost always stored in IEEE 754 format, which is quite different from the way you imagine.

Laurenz Albe
  • 209,280
  • 17
  • 206
  • 263
1

The floating point representation in Standard C is decomposed in 3 groups: sign, mantissa, exponent. Here you can see how to print it, reading it bit with bit and other informations about the floating point implemented by the C standard.

alinsoar
  • 15,386
  • 4
  • 57
  • 74
0

How it is stored depends on your system specifics. But generally the most significant bit is sign, then 8 bit exponent offset by 127, then 21 mantissa representing the fractions being summed.

#include <stdio.h>
#include <stdint.h>

void main(void){

    int i;
    union
    {
        uint8_t  data_to_send[12];
        float    float_value;
    } union_var;

    union_var.float_value =  32.0800018310;

    unsigned char sign = 43 + ((union_var.data_to_send[3] >> 7) << 1);

    int exponent = ((union_var.data_to_send[3] & 0x7F) << 1) + (union_var.data_to_send[2] >> 7) - 127;

    int mantissa_store = (union_var.data_to_send[2] & 0x7F << 16) + (union_var.data_to_send[1] << 8) + union_var.data_to_send[0];

    double mantissa = 1.0; 
    double part = 0.5;
    for (i=22;i>=0;i--) 
    {
        if (mantissa_store & (1<<i))
        {
            mantissa += part;
        }
        part /= 2;
    }

    printf("Float is: %c 2^%d * %.12f\n",sign,exponent, mantissa);
    printf("Mantissa value: %d\n",mantissa_store);
}

output:

Float is: + 2^5 * 1.002500057220
Mantissa value: 20972
Secto Kia
  • 990
  • 4
  • 12
  • The significand (the preferred term; “mantissa” is more properly the fraction part of a logarithm) of an IEEE-754 basic 32-bit binary floating-point number has 24 bits, of which 23 are encoded in the significand field and one in the exponent field. 21 is not correct. – Eric Postpischil Mar 01 '19 at 11:00
  • `sign = 43…` relies on ASCII, unnecessarily and without documenting that requirement. – Eric Postpischil Mar 01 '19 at 11:05
  • This code relies on endianness. The loop to compute the significand is unnecessary; the integer significand can be directly converted to `float` and then scaled. It should be mentioned that this code does not handle subnormals, infinities, or NaNs. The code relies on `int` having at least 24 bits, which C does not guarantee. – Eric Postpischil Mar 01 '19 at 11:09
0

float value which is 32.0800018310 (binary = 100000.0001010001111011).

You are confusing "Fixed-point number" representation with "floating-point number" representation.

The number 32.0800018310 do have the binary representation 00000000.0100000.00010100.01111011 if stored as a fixed-point number with scaling factor 2^16

That is:

2^16 is 65536

00000000.0100000.00010100.01111011 as normal binary number is  2102395

and

2102395 / 65536 is 32.0800018310

So as a fixed-point number with scaling factor 2^16 your binary representation is correct but ...

Computers don't store floating point as fixed-point numbers. The common way is to use IEEE 754 format.

So when you print your float in binary you'll see the binary representation for IEEE 754 instead of the values you expected.

Fixed-point format is not part of the C standard but there are a number of C fixed-point libraries that can be downloaded from the net if you want to play with fixed-point math.

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63