0

Im trying to get the hexadecimal representation of a floating point value and so far I have been able to accomplish this:

float num = 263.3
int hexInt = *(int*)#
printf("%d", hexInt); // some integer value i dont understand
printf("%x", hexInt); //the hexidecimal represenation of num

I'm just curious as to what the integer hexInt represents when formatted as an integer.

ikegami
  • 367,544
  • 15
  • 269
  • 518
nandy
  • 1
  • 1
  • 1
    What is your question ? – Eugene Sep 30 '19 at 23:24
  • 1
    Google "IEEE 754" – Lee Daniel Crocker Sep 30 '19 at 23:25
  • 2
    You're printing the exact same number out twice, just displayed in different bases. – Shawn Sep 30 '19 at 23:26
  • 1
    If `hexInt`'s value were well-defined in the first place, then its value when formatted as a *decimal* integer would represent the same number as its value when formatted as a *hexadecimal* integer. – John Bollinger Sep 30 '19 at 23:28
  • See also this StackOverflow article: https://stackoverflow.com/questions/26011546/float-point-to-hex-in-c-sharp – Su Llewellyn Sep 30 '19 at 23:31
  • 2
    And of course, strictly spoken, the program exposes undefined behavior: You cannot access a float object through an int expression. The hex output is also not particularly useful because it does potentially (and if you are on a PC, surely) not show the bytes in the order in which they reside in memory. Cast the address to a *char pointer*, obtain the number of bytes with `sizeof(float)`, and then print each byte value. *That* is useful and allowed (you can access any object through a `char` expression). – Peter - Reinstate Monica Sep 30 '19 at 23:31
  • 1
    In C, the `%A` format for `printf()` will print the hexadecimal representation of the `double` value that corresponds to the `float` number: `printf("%A\n", num):`. But there isn't a standardized way to print the hexadecimal value of the `float` because any `float` is automatically promoted to `double` by the default argument promotion rules for functions like `printf()` with a variable argument list (C11 [§6.5.2.2 Function calls ¶7](https://port70.net/~nsz/c/c11/n1570.html#6.5.2.2p7)), and there's no length modifier to shorten a `double` to a `float`. – Jonathan Leffler Sep 30 '19 at 23:41
  • @PeterA.Schneider: Integers and floating-point values are typically stored in memory in the same byte order, and the descriptions of floating-point format match the ordering of the bits in an integer. So, yes, one would want to see the floating-point representation interpreted as an integer with the same byte ordering used by the architecture. Printing the bytes in address order is more likely to reverse them and is not the desired method. – Eric Postpischil Oct 01 '19 at 02:06
  • @EricPostpischil But it will *still* not represent the memory layout on a little endian machine and it will be a mix between mantissa and exponent which is useless as a number. I really don't quite see the point. – Peter - Reinstate Monica Oct 01 '19 at 06:00
  • @PeterA.Schneider: People on occasion work directly with the representation of a floating-point number. For example, when implementing the standard routines `sin` or `log`, it is necessary to extract the exponent and significand fields as part of performing argument reduction. Implementing similar routines that are not part of the standard library would have similar requirements. Although these extractions can be done with `frexp`, it may be inadequate for performance reasons. So the representation is worked with directly. For this purpose, having the bytes in memory order would be unhelpful… – Eric Postpischil Oct 01 '19 at 10:48
  • @PeterA.Schneider: … When memory order is little endian but your byte-by-byte method assembles them in big-endian order, one would have to reverse the bytes or otherwise reorder them to reconstruct both the exponent field and the significand field. In contrast, taking the bytes in the same order as an unsigned integer yields exactly the desired representation. – Eric Postpischil Oct 01 '19 at 11:38
  • @JonathanLeffler Unclear why "there's no length modifier to shorten a double to a float" is a concern as `"%a"` prints "the precision is sufficient for an exact representation of the value" - IOWs output is shorten by not having trailing zeros. Still likely some wiggle room for spec interpretation though. – chux - Reinstate Monica Oct 01 '19 at 13:10

2 Answers2

0

... to get the hexadecimal representation of a floating point value

Simply use "%a\n"

printf("%a\n", 263.3f);  // May print `0x1.074cccp+8
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Note that it is the representation of the `double` value because `263.3f` is converted to `double` before being passed to the `printf()` function. – Jonathan Leffler Oct 01 '19 at 07:10
0

To see the data that encodes a floating-point object, one can use:

#include <inttypes.h> // For printf format PRIx32.
#include <stdint.h>   // For uint32_t.
#include <string.h>   // For memcpy.
...
// Copy bytes of float num into bytes of uint32_t x.
uint32_t x;
_Static_assert(sizeof x == sizeof num, "num must be 32 bits."); // Check size.
memcpy(&x, &num, sizeof x);

// Print x as a hexadecimal numeral.
printf("0x%" PRIx32 "\n", x);

The value in x is a number. Whether it is printed as hexadecimal or decimal, the same value is printed, just in different bases. This does not change the number in x. Printing it in hexadecimal is more useful for humans to be able to see the components of the floating-point format in the display. But the value is the same regardless of whether it is shown in hexadecimal or decimal.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312