Created
September 3, 2015 23:57
-
-
Save JayFoxRox/1221aa6df6074ad6155e to your computer and use it in GitHub Desktop.
This file contains 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
// reset && clear && clang test-depth-fp.c && ./a.out 123 | |
#include <stdio.h> | |
#include <stdint.h> | |
#include <stdlib.h> | |
#include <assert.h> | |
/* Found these by checking values represented by 0xFFFF and 0xFEFFFF */ | |
#define F16_MAX 511.9375f | |
#define F24_MAX 340279770772509196049560342183603601408.0f | |
/* [0.0, 511.9375] to 16 bit */ | |
static uint16_t convert_double_to_f16(double d) { | |
assert(d >= 0.0); | |
if (d == 0.0) { return 0x0000; } | |
uint64_t* i = (uint64_t*)&d; | |
return (*i >> 40) - 0x3F8000; | |
} | |
/* 16 bit to [0.0, 511.9375] */ | |
static double convert_f16_to_double(uint16_t f16) { | |
if (f16 == 0x0000) { return 0.0; } | |
uint64_t i = (f16 + 0x3F8000ULL) << 40; | |
return *(double*)&i; | |
} | |
/* [0.0, 511.9375] to 16 bit */ | |
static uint16_t convert_float_to_f16(float f) { | |
assert(f >= 0.0); | |
if (f == 0.0) { return 0x0000; } | |
uint32_t* i = (uint32_t*)&f; | |
return (*i >> 11) - 0x3F8000; | |
} | |
/* 16 bit to [0.0, 511.9375] */ | |
static float convert_f16_to_float(uint16_t f16) { | |
if (f16 == 0x0000) { return 0.0; } | |
uint32_t i = (f16 << 11) + 0x3C000000; | |
return *(float*)&i; | |
} | |
/* [0.0, F24_MAX] to 24 bit */ | |
static uint32_t convert_double_to_f24(double d) { | |
assert(d >= 0.0); | |
if (d == 0.0) { return 0x000000; } | |
uint64_t* i = (uint64_t*)&d; | |
return ((*i >> 36) - 0x3800000) & 0xFFFFFF; | |
} | |
/* 24 bit to [0.0, F24_MAX] */ | |
static double convert_f24_to_double(uint32_t f24) { | |
assert(!(f24 >> 24)); | |
f24 &= 0xFFFFFF; | |
if (f24 == 0x000000) { return 0.0; } | |
uint64_t i = (f24 + 0x3800000ULL) << 36; | |
return *(double*)&i; | |
} | |
/* [0.0, F24_MAX] to 24 bit */ | |
static uint32_t convert_float_to_f24(float d) { | |
assert(d >= 0.0); | |
if (d == 0.0) { return 0x000000; } | |
uint32_t* i = (uint32_t*)&d; | |
return ((*i >> 7) - 0x3000000) & 0xFFFFFF; | |
} | |
/* 24 bit to [0.0, F24_MAX] */ | |
static float convert_f24_to_float(uint32_t f24) { | |
assert(!(f24 >> 24)); | |
f24 &= 0xFFFFFF; | |
if (f24 == 0x000000) { return 0.0; } | |
uint32_t i = f24 << 7; | |
return *(float*)&i; | |
} | |
int main(int argc, char* argv[]) { | |
double zd = atof(argv[1]); | |
float zf = zd; | |
uint16_t f16d = convert_double_to_f16(zd); | |
double r16d = convert_f16_to_double(f16d); | |
printf("XB16D: Converted %f to %04X to %f\n", zd, f16d, r16d); | |
uint16_t f16f = convert_float_to_f16(zf); | |
float r16f = convert_f16_to_float(f16f); | |
printf("XB16F: Converted %f to %04X to %f\n", zf, f16f, r16f); | |
uint32_t f24d = convert_double_to_f24(zd); | |
double r24d = convert_f24_to_double(f24d); | |
printf("XB24D: Converted %f to %06X to %f\n", zd, f24d, r24d); | |
uint32_t f24f = convert_float_to_f24(zf); | |
double r24f = convert_f24_to_float(f24f); | |
printf("XB24F: Converted %f to %06X to %f\n", zf, f24f, r24f); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment