#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; } for (uint32_t i = 0; i < 254-127-23; i++) { f2 = f2 / 2.0f; } if (mul_count > 0xFE) { // subnormal uint32_t mantissa = ((uint32_t) f2) & 0b11111111111111111111111; // add back the implicit leading 1 that would be explicit in subnormals mantissa |= 1 << 23; // shift into place by the number of extra times we were allowed to multiply // (indicating the first leading 1 position) mantissa >>= (mul_count - 0xFE + 1); printf("result: "); printb((sign << 31) | mantissa); } else { // normal // 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; 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); getbits_meow(0.00000000000000000000000000000000000000001f); }