Skip to content

Instantly share code, notes, and snippets.

@yurapyon
Last active February 16, 2017 22:06
Show Gist options
  • Save yurapyon/e859611a851a3b86a82e57415572acf3 to your computer and use it in GitHub Desktop.
Save yurapyon/e859611a851a3b86a82e57415572acf3 to your computer and use it in GitHub Desktop.
#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