Skip to content

Instantly share code, notes, and snippets.

@JayFoxRox
Created September 3, 2015 23:57
Show Gist options
  • Save JayFoxRox/1221aa6df6074ad6155e to your computer and use it in GitHub Desktop.
Save JayFoxRox/1221aa6df6074ad6155e to your computer and use it in GitHub Desktop.
// 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