Skip to main content
added 431 characters in body
Source Link
Majenko
  • 105.5k
  • 5
  • 80
  • 138

You need to convert the format by overlaying one type on top of the other, rather than casting from one type to another.

1000 as an integer cast to a floating point value is still 1000.

You have an example of how it can be done in comments:

//float y = *(float*)&x;

However this method is called type punning and is frowned upon (there are compiler options that can prevent it being used). Instead using a union is a better option:

union ifloat {
    uint8_t bytes[4];
    float val;
};

void setup() {
    ifloat f;
    Serial.begin(115200);
    f.bytes[3] = 0x43;
    f.bytes[2] = 0x59;
    f.bytes[1] = 0xE1;
    f.bytes[0] = 0x89;
    Serial.println(f.val, 4);
    
}

void loop() {
}

So you can get the byte order right your current numeric value of 1129963913 is 0x4359E189 in hexadecimal. Byte 3 is therefore the most significant byte and byte 0 the least significant. Note that it can change from system to system depending on the endianness of the chip.

How it works is quite simple. You have 4 bytes in memory, and the union just gives you different views of those 4 bytes.

You can either see them as four individual bytes (f.bytes[0-3]) or as a floating point value (f.val).

You can understand more about how the four bytes describe the floating point number by understanding more about the IEEE 754 Single Precision Floating Point Format.


You can achieve the same thing using reinterpret_cast, but that has to be done using pointers, not the values, which makes it a little more complex to understand:

// Your incoming 32-bit value
uint32_t l = 1129963913; 

// A pointer to the same memory with a different type
float *f = reinterpret_cast<float *>(&l);

// Print the *content* of the pointer interpreted as a float.
Serial.println(*f, 3); 

You need to convert the format by overlaying one type on top of the other, rather than casting from one type to another.

1000 as an integer cast to a floating point value is still 1000.

You have an example of how it can be done in comments:

//float y = *(float*)&x;

However this method is called type punning and is frowned upon (there are compiler options that can prevent it being used). Instead using a union is a better option:

union ifloat {
    uint8_t bytes[4];
    float val;
};

void setup() {
    ifloat f;
    Serial.begin(115200);
    f.bytes[3] = 0x43;
    f.bytes[2] = 0x59;
    f.bytes[1] = 0xE1;
    f.bytes[0] = 0x89;
    Serial.println(f.val, 4);
    
}

void loop() {
}

So you can get the byte order right your current numeric value of 1129963913 is 0x4359E189 in hexadecimal. Byte 3 is therefore the most significant byte and byte 0 the least significant. Note that it can change from system to system depending on the endianness of the chip.

How it works is quite simple. You have 4 bytes in memory, and the union just gives you different views of those 4 bytes.

You can either see them as four individual bytes (f.bytes[0-3]) or as a floating point value (f.val).

You can understand more about how the four bytes describe the floating point number by understanding more about the IEEE 754 Single Precision Floating Point Format.

You need to convert the format by overlaying one type on top of the other, rather than casting from one type to another.

1000 as an integer cast to a floating point value is still 1000.

You have an example of how it can be done in comments:

//float y = *(float*)&x;

However this method is called type punning and is frowned upon (there are compiler options that can prevent it being used). Instead using a union is a better option:

union ifloat {
    uint8_t bytes[4];
    float val;
};

void setup() {
    ifloat f;
    Serial.begin(115200);
    f.bytes[3] = 0x43;
    f.bytes[2] = 0x59;
    f.bytes[1] = 0xE1;
    f.bytes[0] = 0x89;
    Serial.println(f.val, 4);
    
}

void loop() {
}

So you can get the byte order right your current numeric value of 1129963913 is 0x4359E189 in hexadecimal. Byte 3 is therefore the most significant byte and byte 0 the least significant. Note that it can change from system to system depending on the endianness of the chip.

How it works is quite simple. You have 4 bytes in memory, and the union just gives you different views of those 4 bytes.

You can either see them as four individual bytes (f.bytes[0-3]) or as a floating point value (f.val).

You can understand more about how the four bytes describe the floating point number by understanding more about the IEEE 754 Single Precision Floating Point Format.


You can achieve the same thing using reinterpret_cast, but that has to be done using pointers, not the values, which makes it a little more complex to understand:

// Your incoming 32-bit value
uint32_t l = 1129963913; 

// A pointer to the same memory with a different type
float *f = reinterpret_cast<float *>(&l);

// Print the *content* of the pointer interpreted as a float.
Serial.println(*f, 3); 
added 468 characters in body
Source Link
Majenko
  • 105.5k
  • 5
  • 80
  • 138

You need to convert the format by overlaying one type on top of the other, rather than casting from one type to another.

1000 as an integer cast to a floating point value is still 1000.

You have an example of how it can be done in comments:

//float y = *(float*)&x;

However this method is called type punning and is frowned upon (there are compiler options that can prevent it being used). Instead using a union is a better option:

union ifloat {
    uint8_t bytes[4];
    float val;
};

void setup() {
    ifloat f;
    Serial.begin(115200);
    f.bytes[3] = 0x43;
    f.bytes[2] = 0x59;
    f.bytes[1] = 0xE1;
    f.bytes[0] = 0x89;
    Serial.println(f.val, 4);
    
}

void loop() {
}

So you can get the byte order right your current numeric value of 1129963913 is 0x4359E189 in hexadecimal. Byte 3 is therefore the most significant byte and byte 0 the least significant. Note that it can change from system to system depending on the endianness of the chip.

How it works is quite simple. You have 4 bytes in memory, and the union just gives you different views of those 4 bytes.

You can either see them as four individual bytes (f.bytes[0-3]) or as a floating point value (f.val).

You can understand more about how the four bytes describe the floating point number by understanding more about the IEEE 754 Single Precision Floating Point Format.

You need to convert the format by overlaying one type on top of the other, rather than casting from one type to another.

1000 as an integer cast to a floating point value is still 1000.

You have an example of how it can be done in comments:

//float y = *(float*)&x;

However this method is called type punning and is frowned upon (there are compiler options that can prevent it being used). Instead using a union is a better option:

union ifloat {
    uint8_t bytes[4];
    float val;
};

void setup() {
    ifloat f;
    Serial.begin(115200);
    f.bytes[3] = 0x43;
    f.bytes[2] = 0x59;
    f.bytes[1] = 0xE1;
    f.bytes[0] = 0x89;
    Serial.println(f.val, 4);
    
}

void loop() {
}

So you can get the byte order right your current numeric value of 1129963913 is 0x4359E189 in hexadecimal. Byte 3 is therefore the most significant byte and byte 0 the least significant. Note that it can change from system to system depending on the endianness of the chip.

You need to convert the format by overlaying one type on top of the other, rather than casting from one type to another.

1000 as an integer cast to a floating point value is still 1000.

You have an example of how it can be done in comments:

//float y = *(float*)&x;

However this method is called type punning and is frowned upon (there are compiler options that can prevent it being used). Instead using a union is a better option:

union ifloat {
    uint8_t bytes[4];
    float val;
};

void setup() {
    ifloat f;
    Serial.begin(115200);
    f.bytes[3] = 0x43;
    f.bytes[2] = 0x59;
    f.bytes[1] = 0xE1;
    f.bytes[0] = 0x89;
    Serial.println(f.val, 4);
    
}

void loop() {
}

So you can get the byte order right your current numeric value of 1129963913 is 0x4359E189 in hexadecimal. Byte 3 is therefore the most significant byte and byte 0 the least significant. Note that it can change from system to system depending on the endianness of the chip.

How it works is quite simple. You have 4 bytes in memory, and the union just gives you different views of those 4 bytes.

You can either see them as four individual bytes (f.bytes[0-3]) or as a floating point value (f.val).

You can understand more about how the four bytes describe the floating point number by understanding more about the IEEE 754 Single Precision Floating Point Format.

Source Link
Majenko
  • 105.5k
  • 5
  • 80
  • 138

You need to convert the format by overlaying one type on top of the other, rather than casting from one type to another.

1000 as an integer cast to a floating point value is still 1000.

You have an example of how it can be done in comments:

//float y = *(float*)&x;

However this method is called type punning and is frowned upon (there are compiler options that can prevent it being used). Instead using a union is a better option:

union ifloat {
    uint8_t bytes[4];
    float val;
};

void setup() {
    ifloat f;
    Serial.begin(115200);
    f.bytes[3] = 0x43;
    f.bytes[2] = 0x59;
    f.bytes[1] = 0xE1;
    f.bytes[0] = 0x89;
    Serial.println(f.val, 4);
    
}

void loop() {
}

So you can get the byte order right your current numeric value of 1129963913 is 0x4359E189 in hexadecimal. Byte 3 is therefore the most significant byte and byte 0 the least significant. Note that it can change from system to system depending on the endianness of the chip.