Last active
February 16, 2017 22:06
-
-
Save yurapyon/e859611a851a3b86a82e57415572acf3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdint.h> | |
#include <math.h> | |
#define nl() printf("\n") | |
#define fl_mark() printf("s/exp /mantissa\n"); | |
#define is_finite(_fl) ((_fl & 0x7F800000) != 0x7F800000) | |
#define is_normalized(_fl) is_finite(~(_fl)) | |
void | |
print_u32(void *obj) | |
{ | |
if (!obj) return; | |
uint32_t buf = *(uint32_t *)obj; | |
for (uint32_t ct = 1 << 31; ct; ct >>= 1) { | |
printf(buf & ct ? "1" : "0"); | |
} | |
} | |
// exp is locked between -23 and 23 | |
// handle more special cases | |
// truncating and rounding | |
void | |
print_float(float fl) | |
{ | |
const uint32_t buf = *(uint32_t *)&fl; | |
int is_pos = !(buf & 1 << 31); | |
if (!is_normalized(buf)) { | |
if (buf & 0x007FFFFF) { | |
printf("denormalized"); | |
return; | |
} | |
} | |
if (!is_finite(buf)) { | |
printf("%s%s" | |
, is_pos ? "" : "-" | |
, buf & 0x007FFFFF ? "nan" : "inf"); | |
return; | |
} | |
int exp = (uint8_t)(buf >> 23) - 127; | |
uint32_t mantissa = buf & 0x007FFFFF | 0x00800000; | |
uint32_t int_part = mantissa >> (23 - exp); | |
if (exp < 0) { | |
mantissa >>= -exp; | |
int_part = exp = 0; | |
} | |
uint64_t mult = 1000000000000000000 >> 1; | |
uint64_t dec_part = 0; | |
for (uint32_t ct = 1 << (22 - exp); ct; ct >>= 1) { | |
if (mantissa & ct) { | |
dec_part += mult; | |
// radix or whatev | |
// inc max decimal places | |
} | |
mult >>= 1; | |
} | |
// round and truncate | |
printf("%s%u.%018lu", is_pos ? "" : "-", int_part, dec_part); | |
} | |
int | |
main(void) | |
{ | |
print_float(INFINITY); nl(); | |
print_float(NAN); nl(); | |
print_float(-INFINITY); nl(); | |
print_float(-NAN); nl(); | |
nl(); | |
print_float(0.); nl(); | |
print_float(*(float *)&(uint32_t) { 0x00400000 }); nl(); | |
nl(); | |
print_float(1.); nl(); | |
print_float(2.); nl(); | |
print_float(-2.); nl(); | |
print_float(45.); nl(); | |
print_float(-45.5); nl(); | |
print_float(30.125); nl(); | |
print_float(30.03042145987018); nl(); | |
nl(); | |
print_float(0.5); nl(); | |
print_float(0.12345); nl(); | |
print_float(0.012345); nl(); | |
print_float(0.000045); nl(); | |
nl(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment