What would be the best way to convert from hexadecimal textual representation to it's IEEE754 representation in double precision (that would result in minimal rounding)?
For example, converting:
-0x1.f8b791cafcdefp 4
to C03F8B791CAFA2C0
My current method is to convert from hexadecimal to a double
, then convert this to IEEE754 representation, but this obviously involves dubious levels of rounding.
CodePudding user response:
Would you please try something like:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
union ieee754 {
uint64_t i;
double f;
};
int main()
{
char str[] = "-0x1.f8b791cafcdefp 4";
union ieee754 val;
val.f = strtod(str, (char **)NULL); // might better to check error
printf("%"PRIX64"\n", val.i);
return 0;
}
Output:
C03F8B791CAFCDEF
Alternatively, here is the direct calculation from the substring just with the bit operations based on the binary64 definition of IEEE754.
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main()
{
// "-0x1.f8b791cafcdefp 4" is composed of follows:
uint64_t sign = 1; // negative value
uint64_t exponent = 4 1023; // 1023 offset
uint64_t fraction = 0xf8b791cafcdef; // strip the leading "1." off
uint64_t val = (sign << 63) | (exponent << 52) | fraction;
printf("%"PRIX64"\n", val);
return 0;
}
Please note I don't intend to spoil OP's motivation. Posted the answer just in case...
CodePudding user response:
Converting from hex representation to IEEE754 double
representation will only involve rounding if there are more decimals than the precision of the double
type. This can happen if the textual representation was produced from a long double
.
Using strtod()
is the best way to handle this.