Last active
January 24, 2018 10:55
-
-
Save holland01/3bf88ee42217a97c324b0665695d1168 to your computer and use it in GitHub Desktop.
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)
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
#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