Skip to content

Instantly share code, notes, and snippets.

@ityonemo
Created May 11, 2014 00:38
Show Gist options
  • Save ityonemo/fc5e4c2fa26200c91e91 to your computer and use it in GitHub Desktop.
Save ityonemo/fc5e4c2fa26200c91e91 to your computer and use it in GitHub Desktop.
minifloat.c
#include <stdio.h>
#include <string.h>
#include <stdint.h>
typedef uint8_t minifloat;
/*
minifloat variable: sign bit, then three bits of exponent, and four bits of
mantissa. Like the 1:4:3 minifloat, but instead with the exponent as the
least significant bits.
|Sx|XXX|Sv|VVV|
*/
#define M_ALL 0xFF
#define M_SGN 0x08
#define M_VAL 0x0F
#define M_PRT 0x07
#define M_ESN 0x80
#define M_EXP 0xF0
#define M_EPT 0x70
/* converts a minifloat value to the corresponding big float value. */
float to_float_r(minifloat v){
/*uses a representational conversion mechanism*/
/*define a "product accumulator" value*/
float acc = 1;
/*separate the value part away from the exponent part, and alter the
accumulator accordingly*/
acc *= ((v & M_SGN) ?
(-1 * (M_ALL ^ (M_EXP | (int8_t) v))) :
(M_VAL & v));
/*now separate the exponential part away from the value part and alter
the accumulator accordingly. */
acc *= ((v & M_ESN) ? 1 / (float)(1 << ((M_ALL ^ v) >> 4)) : 1 << (v >> 4));
return acc;
}
/*creates the additive inverse of v*/
minifloat addinv(minifloat v){
return v ^ M_VAL;
}
/*performs addition on v */
minifloat add(minifloat u, minifloat v){
/*first check to see if u is greater than v*/
}
main()
{
minifloat one = 0x01;
minifloat two = 0x02;
minifloat mone = 0x0E;
minifloat half = 0xE1;
minifloat quart = 0xD1;
minifloat four = 0x04;
minifloat alsofour = 0x12;
minifloat stillfour = 0x21;
printf("value: 0X%02X %4.2f\n", one, to_float_r(one));
printf("value: 0X%02X %4.2f\n", two, to_float_r(two));
printf("value: 0X%02X %4.2f\n", mone, to_float_r(mone));
printf("value: 0X%02X %4.2f\n", half, to_float_r(half));
printf("value: 0X%02X %4.2f\n", quart, to_float_r(quart));
printf("value: 0X%02X %4.2f\n", four, to_float_r(four));
printf("value: 0X%02X %4.2f\n", alsofour, to_float_r(alsofour));
printf("value: 0X%02X %4.2f\n", stillfour, to_float_r(stillfour));
}
@AnastasiaDunbar
Copy link

AnastasiaDunbar commented Sep 30, 2019

In JavaScript:

var M_ALL=0xFF, //11111111
    M_SGN=0x08, //00001000
    M_VAL=0x0F, //00001111
    M_PRT=0x07, //00000111 (unused)
    M_ESN=0x80, //10000000
    M_EXP=0xF0, //11110000
    M_EPT=0x70; //01110000 (unused)
function decodeMinifloat(v){
	var acc=1; //Product accumulator.
	//Separate the value part away from the exponent part, and alter the accumulator accordingly.
	acc*=(v&M_SGN)?
		(-1*(M_ALL^(M_EXP|v))):
		(M_VAL&v);
	//Now separate the exponential part away from the value part and alter the accumulator accordingly.
	acc*=(v&M_ESN)?1/(1<<((M_ALL^v)>>4)):1<<(v>>4);
	return acc;
}
[
	[0X01,1],
	[0X02,2],
	[0X0E,-1],
	[0XE1,0.50],
	[0XD1,0.25],
	[0X04,4],
	[0X12,4],
	[0X21,4]
].forEach(x=>{
	console.log(`value: 0x${x[0].toString(16).padStart(2,"0")} or ${x[0].toString(2).padStart(8,"0")}, expected: ${x[1]}, got: ${decodeMinifloat(x[0])}`);
});
/*
value: 0x01 or 00000001, expected: 1,    got: 1
value: 0x02 or 00000010, expected: 2,    got: 2
value: 0x0e or 00001110, expected: -1,   got: -1
value: 0xe1 or 11100001, expected: 0.5,  got: 0.5
value: 0xd1 or 11010001, expected: 0.25, got: 0.25
value: 0x04 or 00000100, expected: 4,    got: 4
value: 0x12 or 00010010, expected: 4,    got: 4
value: 0x21 or 00100001, expected: 4,    got: 4
*/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment