# Storing a float as a byte

I am using an NTC to read temperature. I use the Steinhart-Hart formula to calculate the temperature from the Resistance of the NTC. The output of that formula is a float (double integer, 4 bytes).
I also want to log the results in memory. For that I have a couple of choices
Store the floating point variable : that will cost me 32 bits of memory for every temperature value logged
Store the original NTC reading and just pull that through the Steinhart-Hart formula again when needed, that will cost me 16 bits for every temperature logged.
As I really don’t need the high decimal precision that a floating point value can give and as I really didn’t expect my temperature range to go outside -15 to +30 degrees Celcius, both 16 bits and 32 bits seemed serious overkill.

So I was wondering if I just couldn’t store it in in 1 Byte. As the Steinhart-Hart formula gives an approximation of the temperature, one can wonder how precise of a reading one needs, but I decided I wanted a solution of 0.25 degrees, though no doubt 0.5 degrees would have been enough already.
I figured I would use the MSB for the sign bit, that left 7 bits
decimal number 31 is equal to 0b00011111, so to cover my range I needed 5 bits for the temperature that left 2 bits
In those two bits I can store numbers 0-3, that I could use for the decimal fraction.
Extracting the essential bits from the binary level of the float seemed to much of a problem so I mainly worked with the decimal values.
In the function floatToByte I do a couple of essential things: I first check if it is a positive or a negative number as that determines the MSB I need to set in my byte. Then Itake the absolute value of the float so I get rid of o potential minus value, which would complicate calculations.
Then I turn the float into an integer and subtract that from the float. That leaves the decimal fraction. In order to keep at least some precision in that I have to put that in a double. Initially it was my idea to turn the values 0-9 into 0-3, but a simple division by 3 didnt have the desired effect as ‘9’ was sometimes 0.89 which by division would give a 2, So I decided on some simple ‘if’ conditions to convert the double fraction into half a nibble.
I then would shift the 5 bit temperature 2 bits to the right bitwise OR it with the fraction (on the two least significant bits and bitwise OR it with the sign bit.
That gave me temperature values that I can store in 1 Byte of EEPROM.

The way back – from memory byte to sensible temperature. Goes the other way around

```byte floatToByte(float temp2)
{
byte sign = 128;
if (temp2 >= 0) {
sign = 0;
}
double temp = abs(temp2);

int heel = int(temp);
double fractie = temp - heel;

fractie = (temp - heel);
fractie = fractie * 100;
byte fractie2 = 0;
if (fractie >= 25) {
fractie2 = 1;
}
if (fractie >= 50) {
fractie2 = 2;
}
if (fractie >= 75) {
fractie2 = 3;
}
byte temperatuur = (((heel << 2) | fractie2) | sign);
return temperatuur;
}

void getTempByte(byte Temp)
{
float temperatuurCelcius;
if (Temp & 0b10000000) // check negative
{
Temp = Temp ^ 0b10000000; // knock out MSB byte
double fractie = (Temp & 0b00000011);
byte body = (Temp >> 2);
Serial.println(-1 * (body + (fractie * 0.25)));
}
else
{
byte fractie = (Temp & 0b00000011);
byte body = (Temp >> 2);
Serial.println(body + fractie * 0.25);
}

}
void setup() {
Serial.begin(9600);
byte x = floatToByte(+31.10);
Serial.println(x, BIN);
x = floatToByte(+31.25);
Serial.println(x, BIN);
x = floatToByte(31.50);
Serial.println(x, BIN);
x = floatToByte(+31.75);
Serial.println(x, BIN);
x = floatToByte(-31.75);
Serial.println(x, BIN);
x = floatToByte(+0.15);
Serial.println(x, BIN);
Serial.println("temperatuur ");
getTempByte(0b1111101);

}
void loop() {
// put your main code here, to run repeatedly:

}
```

## 2 thoughts on “Storing a float as a byte”

1. Jeroen says:

I must be missing something here. Why didn’t you simply multiply the temperature float by 4, then take the int value of that? The last two bits would then represent 0.25 degree steps?

1. Arduino says:

I dont think you are missing something. Most likely I had a bind spot at that time. I was trying to come up with a formula for the fractionbut just couldnt wrap my head around it. Good input, thanks

This site uses Akismet to reduce spam. Learn how your comment data is processed.