Converting from bytes to float via Union not working on ESP32

The clang code avoids an actual memcpy() - I have no objection to extra overhead to account for unknown alignment.

@michael_st

Serial.println(test1.value, 2); //shows: 5.00

Thank you all! I will definitely be implementing using memcpy now that I know that it is the correct way of doing a problem like this. As I am not a compiler developer I am not completely sure of the purpose of memcpy (I looked at the documentation but couldn't completely understand) and would love to hear more about it.

In the end, my main issue was not knowing what my test values should output. The test that I had originally should have printed zero but I assumed that anything other than all zeros should result in a non zero number. I was wrong and should have checked that before posting.

Thank you @6v6gt for catching that operator priority mistake!

Is it "operator priority" or "operator precedence"?

it’s a non issue really - everyone gets the point but indeed It’s technically called precedence in the spec

https://en.cppreference.com/w/cpp/language/operator_precedence

Associativity also plays a role in this if you want to dig in.

The word priority is used as well to describe what precedence means - you’ll find explanations such as

Descending precedence refers to the priority of the grouping of operators and operands. Considering an expression, an operator which is listed on some row will be grouped prior to any operator that is listed on a row further below it.

Not sure it’s an interesting debate…

2 Likes

Problem is with the pupils who frequently ask for the reference if the word/terminology/vocabulary is used for the fiist time.

To explain the meaning of precedence, of course, the priority word must be brought in as you have shown in your quote.

In that sense pupils would likely understand priority better than precedence

But it’s a good Habit to tell them to look up a word if they don’t understand the meaning, so introducing unusual words is good too.

1 Like

You can use pointer variable for type conversion:

1. Given:
binary32 formatted value:

long int y = 0x42963F36;

What is the corresponding float number?
The following codes could be executed on UNO to get the float number which is: 75.12345886.

float y;     //request is placed for four byte wide memory space
long *ptr;  //ptr is a pointer; holds beginning address of above space
ptr = (long*)&y; //address goes into ptr. Read/write 4-byte at a time.
*ptr = 0x42963F36; //32-bit data goes into 4-byte wide space requested
Serial.print(y,8);//shows:75.12345886

2. Given
A float number:

float y = 75.12345678;

What is the the corresponding binary32 formatted value?

The following codes could be executed ion UNO to get the value which is: 42963F36.
float y = 75.12345678;
long *ptr;
ptr = (long*)&y;
long m = *ptr;
Serial.println(m,HEX);//shows:42963F36

Undefined Behavior in C++

Thank you for the information.

1. I knew that union structure suffers from type-punning. Now, I know that pointer has also the same problem.

2. Then I don't understand how the following codes that uses memcpy() are valid and superior to pointer/union for type conversion; I have to still remmeber that the array holds lower byte first.

void setup()
{
  Serial.begin(9600);
  byte intnum[] = {0x36, 0x3F, 0x96, 0x42};
  //valid binary32 formatted value of 75.12345678; lower-byte first
  
  float flnum;  //4-byte space to hold the above pattern 
  memcpy(&flnum, intnum, sizeof(intnum)); //array name holds the basse address of the array
  Serial.print(flnum, 6); //shows: 75.123458; print() method is doing the magic!
}

void loop()
{

}

3. print() is an overloaded method which recognizes the data type of flnum and accordingly selects the following algorithm/formula to evaluate the Real Value of the expected float number.
binary32For

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.