How can I convert two unsigned integers that represent the digit and decimal part of a float, into one float.
I know there are a few ways todo this, like converting the decimal component into a float and multiplying it to get a decimal and added it to the digit, but that does not seem optimal.
I'm looking for the optimal way todo this.
/*
* Get Current Temp in Celecius.
*/
void GetTemp(){
int8_t digit = 0; // Digit Part of Temp
uint16_t decimal = 0; // Decimal Part of Temp
// define variable that will hold temperature digit and decimal part
therm_read_temperature(&temperature, &decimal); //Gets the current temp and sets the variables to the value
}
I want to take the Digit and Decimal parts and convert them to a float type, such that it looks like digit.decimal .
It might look like this in end, but I want to find the MOST optimal solution.
/*
* Get Current Temp in Celecius.
*/
float GetTemp(){
int8_t digit = 0; // Digit Part of Temp
uint16_t decimal = 0; // Decimal Part of Temp
// define variable that will hold temperature digit and decimal part
therm_read_temperature(&temperature, &decimal); //Gets the current temp and sets the variables to the value
float temp = SomeFunction(digit, decimal); //This could be a expression also.
return temp;
}
////UPDATE/// - July 5th
I was able to get the source code instead of leveraging just the library. I posted it in this GIST DS12B20.c.
temperature[0]=therm_read_byte();
temperature[1]=therm_read_byte();
therm_reset();
//Store temperature integer digits and decimal digits
digit=temperature[0]>>4;
digit|=(temperature[1]&0x7)<<4;
//Store decimal digits
decimal=temperature[0]&0xf;
decimal*=THERM_DECIMAL_STEPS_12BIT;
*digit_part = digit;
*decimal_part = decimal;
Although the function will not force us to return separate parts as digit and decimal, reading from the temperature sensor seems to require this (unless i'm missing something and it can be retrieved as a float).
I think the original question still stands as what is the optimal way to make this into a float in C (this is for use with AVR and an 8bit microprocessor, making optimization key) using the two parts or to be able to retrieve it directly as a float.
What you are really running into is using fixed-point numbers. These can be represented in two ways: either as a single integer with a known magnitude or multiplier (ie. "tenths", "hundredths", "thousandths", and so on; example: value from a digital scale in ten-thousandths of a gram, held in a 32-bit integer -- you divide by 10000 to get grams), or as two integers, with one holding the "accumulated" or "integer" value, and the other holding the "fractional" value.
Take a look at the <stdfix.h> header. This declares types and functions to hold these fixed-point numbers, and perform math with them. When adding fractional parts, for example, you have to worry about rolling into the next whole value, for which you then want to increment the accumulator of the result. By using the standard functions you can take advantage of built-in processor capabilities for fixed-point math, such as those present in the AVR, PIC and MPS430 microcontrollers. Perfect for temperature sensors, GPS receivers, scales (balances), and other sensors that have rational numbers but only integer registers or arithmetic.
Here is an article about it: "Fixed Point Extensions to the C Programming Language", https://sestevenson.wordpress.com/2009/09/10/fixed-point-extensions-to-the-c-programming-language/
To quote a portion of that article:
I don’t think the extensions simplify the use of fixed types very much. The programmer still needs to know how many bits are allocated to integer and fractional parts, and how the number and positions of bits may change (during multiplication for example). What the extensions do provide is a way to access the saturation and rounding modes of the processor without writing assembly code. With this level of access, it is possible to write much more efficient C code to handle these operations.
Scott G. Hall Raleigh, NC, USA