-2

I am trying to convert a float to an IEEE-754 Hex representation. The following code works on my Mac.

#include <stdio.h>
#include <stdlib.h>

union Data {
    int i;
    float f;
};


int main() {
    float var = 502.7;
    union Data value;
    value.f = var;
    printf("%08X\n", value.i);
    return 0;
}

This is giving me the expected result of 43FB599A.

When I run this code on an ATmega64a I am getting 0000599A not 04A2599A as originally posted which was a mistake.

The first two bytes are not expected but the final two bytes seem correct?

Any ideas?


As mentioned in the accepted answer the I was assuming that int was 4 bytes. I was writing the code on my mac and sending it to someone that was downloading it to an 8-bit ATmega64a. On the ATmega64a int is 2 bytes, not 4. I changed int to unsigned long which is 4 bytes on the ATmega64a.

In addition, I had to add a length sub-specifier of l to the format given to printf. This is because when given a specifier of x, printf uses a type of unsigned int to interpret the corresponding argument. Adding the length sub-specifier of l tells printf to use the type of unsigned long to interpret the corresponding argument.

Using only the length sub-specifier of l and not changing the variable i to unsigned long was causing printf to grab some extra bytes and output 04A2599A as originally posted. I, of course, needed to change the type of i to unsigned long as well as use the length sub-specifier of l.

http://www.cplusplus.com/reference/cstdio/printf/

user1757006
  • 705
  • 2
  • 12
  • 23
  • At least make it `unsigned int i` – Eugene Sh. Mar 16 '20 at 21:14
  • Also please decide- it is running on ATMega64 or for your Mac? What is the size of `int` on the target system? – Eugene Sh. Mar 16 '20 at 21:17
  • Perhaps `04A2599A` is correct - depends on `float` encoding. Step 1 would be to report the size of `float`, `int`, `union Data`. – chux - Reinstate Monica Mar 16 '20 at 21:53
  • user1757006, Try and report `printf("%a\n", var);` – chux - Reinstate Monica Mar 16 '20 at 22:07
  • 1
    What is the output of `#include ` / `#include ` / `#define p(x) printf(#x " = %d.\n", x)` / `int main(void) { p(FLT_RADIX); p(FLT_MANT_DIG); p(FLT_MIN_EXP); p(FLT_MAX_EXP); }`? What does the compiler documentation say about the floating-point format? – Eric Postpischil Mar 16 '20 at 22:53
  • Read the datasheet and application notes and learn the sizes of the types. A ATMega64 is not a computer. – TomServo Mar 17 '20 at 01:44
  • user1757006, I suspect code was not properly compiled. What is the command used to compile and link? – chux - Reinstate Monica Mar 17 '20 at 10:16
  • also 502.7 is a double literal. You need to use the f prefix to get a float: `float var = 502.7f` – phuclv Mar 18 '20 at 02:07
  • The edits are unsatisfying. Given 16-bit `int`, `printf("%08X\n", value.i);` would generally print “599A” or some other 16-bit value, not “04A25599A”. Technically, the mismatch between `value.i` having type `int` and `%08X` expecting `unsigned int` results in behavior not defined by the C standard, but print “04A25599A” is not a common response to that by most C implementations. So it seems likely something else was occurring, and the information in the question is inadequate to say what, and so the question is not useful for future readers or to keep on Stack Overflow. – Eric Postpischil Mar 18 '20 at 16:20
  • Eric Postpischil, I have edited the post again. Hopefully, this explains in more detail. "04A2599A" is a mistake. It should have been "0000599A". I got the first value when messing about. – user1757006 Mar 18 '20 at 18:31

1 Answers1

0

This processor is an 8 bit one which mean size of int is most likely 2 byte not 4 as your code assume.

Try to use uint32_t rather then int if you can.

Eraklon
  • 4,206
  • 2
  • 13
  • 29