diff --git a/ieee754/float.c b/ieee754/float.c new file mode 100644 index 0000000..e04e72b --- /dev/null +++ b/ieee754/float.c @@ -0,0 +1,96 @@ +#include +#include +#include +#include + +uint32_t getbits(float f) { + union { float f; uint32_t u; } hax; + hax.f = f; + return hax.u; +} + +void printb(uint32_t u) { + for (uint32_t i = 32; i > 0; i--) { + if (i == 31 || i == 23) { + printf(" "); + } + printf("%d", (u >> (i - 1))&1); + } + printf("\n"); +} + +uint32_t getbits_meow(float f) { + printf("original: "); + printb(getbits(f)); + + // these are untested lol + if (f == 0.0f) { + return 0; + } else if (f == -0.0f) { + return 1 << 31; + } else if (f == NAN) { + // not always accurate + // there are multiple kinds of nan + // idk if there's much we can do tbh + return 0xFFFFFFFF; + } else if (f == INFINITY) { + return 0x7F800000; + } else if (f == -INFINITY) { + return 0xFF800000; + } + uint32_t sign = 0; + if (f < 0) { + sign = 1; + f = -f; + } + + uint32_t div_count = 0; + volatile float f2 = f; + while (true) { + volatile float f3 = f2 / 2.0f; + volatile float f4 = f3 * 2.0f; + if (f4 != f2) { + break; + } + div_count++; + f2 = f3; + } + + uint32_t mul_count = 0; + f2 = f; + while (true) { + volatile float f3 = f2 * 2.0f; + volatile float f4 = f3 / 2.0f; + if (f4 != f2) { + break; + } + mul_count++; + f2 = f3; + } + + // TODO : subnormal numbers (div_count == 0 ?) + + // the div count is cool and all but it allows going into subnormal range while maintaing + // equality which is not good + // so we use the mul count + uint32_t exp = 0xFE - mul_count; + + for (uint32_t i = 0; i < 254-127-23; i++) { + f2 = f2 / 2.0f; + } + + uint32_t mantissa = ((uint32_t) f2) & 0b11111111111111111111111; + + printf("result: "); + printb((sign << 31) | ((exp & 0xFF) << 23) | mantissa); + + printf("----------------\n"); +} + +int main() { + getbits_meow(0.00000002f); + getbits_meow(0.001f); + getbits_meow(10.0f); + getbits_meow(100000.0f); + getbits_meow(10000000000.0f); +}