Skip to content

Instantly share code, notes, and snippets.

@holland01
Last active Jan 24, 2018
Embed
What would you like to do?
just some quick routines hobbled together for a computer architecture class (NOTE: this isn't for an assignment, it's used as a separate tool to aid analysis)
#include <stdio.h>
#include <math.h>
#include <stdint.h>
#include <stdbool.h>
enum float_length {
FLTLEN_32,
FLTLEN_64,
FLTLEN_LONG_DOUBLE
};
typedef enum float_length float_length_t;
struct float_unpacked {
float_length_t length;
size_t sign;
size_t exp;
uint64_t mant;
};
typedef struct float_unpacked float_unpacked_t;
static void unpack_float32(float f, float_unpacked_t *unpacked)
{
const uint8_t* bytes = (uint8_t*) &f;
uint8_t sign = bytes[3] >> 7;
uint8_t e = ((bytes[3] & 0x7F) << 1) | (bytes[2] >> 7);
uint32_t m =
((uint32_t)(bytes[2] & 0x7F) << 16)
| ((uint32_t) bytes[1] << 8)
| ((uint32_t) bytes[0]);
unpacked->length = FLTLEN_32;
unpacked->sign = sign;
unpacked->exp = e;
unpacked->mant = m;
}
static float pack_float32(float_unpacked_t *unpacked)
{
uint8_t bytes[sizeof(float)];
bytes[3] =
((uint8_t)(unpacked->sign << 7))
| ((uint8_t)(unpacked->exp & 0xFE) >> 1);
bytes[2] =
((uint8_t)unpacked->exp << 7)
| (uint8_t)((unpacked->mant >> 16) & 0x7F);
bytes[1] = (uint8_t)((unpacked->mant >> 8) & 0xFF);
bytes[0] = (uint8_t)(unpacked->mant & 0xFF);
float ret;
memcpy(&ret, &bytes[0], sizeof(bytes));
return ret;
}
// 1, 8, 23
// bias = -127
static void print_float(float f)
{
float_unpacked_t up;
unpack_float32(f, &up);
printf("Result for %f: \n", f);
printf("\t0x%x 0x%x 0x%x\n\n", up.sign, up.exp, up.mant);
}
// 1, 11, 52
// bias = -1022
static void unpack_float64(double d, float_unpacked_t *unpacked)
{
const uint8_t* bytes = (uint8_t*) &d;
uint8_t sign = bytes[7] >> 7;
uint16_t exp = (((uint16_t)bytes[7] & 0x7f) << 4) | (((uint16_t)bytes[6] & 0xF0) >> 4);
uint64_t m =
(((uint64_t)bytes[6] & 0x0F) << 48)
| (((uint64_t)bytes[5]) << 40)
| (((uint64_t)bytes[4]) << 32)
| (((uint64_t)bytes[3]) << 24)
| (((uint64_t)bytes[2]) << 16)
| (((uint64_t)bytes[1]) << 8)
| (((uint64_t)bytes[0]));
unpacked->length = FLTLEN_64;
unpacked->sign = (uint32_t) sign;
unpacked->exp = (uint32_t) exp;
unpacked->mant = m;
}
// 00000111 11111111
// 0x07 0xFF
static double pack_float64(float_unpacked_t *unpacked)
{
uint8_t bytes[sizeof(double)];
bytes[7] = (uint8_t)unpacked->sign << 7;
bytes[7] |= (uint8_t)((unpacked->exp & 0x7FF) >> 4);
bytes[6] = (uint8_t)(unpacked->exp & 0xF) << 4;
bytes[6] |= (uint8_t)((unpacked->mant >> 48) & 0xF);
bytes[5] = (uint8_t)(unpacked->mant >> 40);
bytes[4] = (uint8_t)(unpacked->mant >> 32);
bytes[3] = (uint8_t)(unpacked->mant >> 24);
bytes[2] = (uint8_t)(unpacked->mant >> 16);
bytes[1] = (uint8_t)(unpacked->mant >> 8);
bytes[0] = (uint8_t)(unpacked->mant & 0xFF);
double ret;
memcpy(&ret, &bytes[0], sizeof(bytes));
return ret;
}
static void print_float64(double d)
{
float_unpacked_t unpacked;
unpack_float64(d, &unpacked);
printf(
"(double) Result for %f:\n\t0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 "\n\n",
d,
unpacked.sign,
unpacked.exp,
unpacked.mant
);
}
void run_float(void)
{
{
float_unpacked_t up;
unpack_float32(2.5f, &up);
float r = pack_float32(&up);
print_float(r);
}
{
float_unpacked_t up;
unpack_float64(2.75, &up);
double r = pack_float64(&up);
print_float64(r);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment