tests-gdb/util/float-convert.c

130 lines
1.6 KiB
C

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
// NEVER DO THIS IN REAL-LIFE PROGRAMS
// UNDEFINED BEHAVIOUR WILL KILL YOUR DOG
// That's horrible way to convert float to it's integer representation
// but it works in our particular case
typedef union
{
double f;
uint64_t i;
} float64;
typedef union
{
float f;
uint32_t i;
} float32;
typedef union
{
long double f;
struct {
uint64_t lo;
uint16_t hi;
};
} float80;
void usage(void)
{
puts("convert <i32|i64|i80|f32|f64|f80> <val> [80bit_hi]");
exit(1);
}
int main(int argc, char **argv)
{
int bits;
int float_to_int;
if(argc < 3) {
usage();
}
switch(argv[1][0]) {
case 'i':
float_to_int = 0;
break;
case 'f':
float_to_int = 1;
break;
default:
usage();
}
bits = atoi(argv[1] + 1);
if(bits != 32 && bits != 64 && bits != 80)
{
usage();
}
if(float_to_int)
{
switch(bits)
{
case 32:
{
float32 f;
f.f = strtof(argv[2], 0);
printf("0x%x", f.i);
break;
}
case 64:
{
float64 f;
f.f = strtod(argv[2], 0);
printf("0x%lx", f.i);
break;
}
case 80:
{
float80 f;
f.f = strtold(argv[2], 0);
printf("0x%4x 0x%lx", f.hi, f.lo);
break;
}
}
}
else
{
switch(bits)
{
case 32:
{
float32 f;
f.i = (uint32_t)strtol(argv[2], 0, 0);
printf("%f", f.f);
break;
}
case 64:
{
float64 f;
f.i = strtoll(argv[2], 0, 0);
printf("%f", f.f);
break;
}
case 80:
{
float80 f;
if (argc < 4) usage();
f.lo = strtoll(argv[2], 0, 0);
f.hi = (uint16_t)strtol(argv[3], 0, 0);
printf("%Lf", f.f);
break;
}
}
}
puts("");
return 0;
}