From 2eb77f8143f19ae33fd63080afa498991cc225a0 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Tue, 8 Dec 2020 01:08:04 +0300 Subject: [PATCH] Add horrible float<>int representation converting utility --- util/Makefile | 10 ++++ util/float-convert.c | 129 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 util/Makefile create mode 100644 util/float-convert.c diff --git a/util/Makefile b/util/Makefile new file mode 100644 index 0000000..23f2142 --- /dev/null +++ b/util/Makefile @@ -0,0 +1,10 @@ +CC ?= cc +CFLAGS ?= -O3 + +float-convert: + $(CC) $(CFLAGS) float-convert.c -o float-convert + +all: float-convert + +clean: + rm float-convert diff --git a/util/float-convert.c b/util/float-convert.c new file mode 100644 index 0000000..72604b6 --- /dev/null +++ b/util/float-convert.c @@ -0,0 +1,129 @@ +#include +#include +#include + +// 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 [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; +}