130 lines
1.6 KiB
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;
|
|
}
|