Many development tools have multiple versions of printf
and related functions, which support differing levels of capabilities. Floating-point math code is bulky and complicated, so including features which aren't used would waste a lot of code space.
Some tools automatically try to figure out which options need to be included, but some aren't very good and some simply require that the programmer explicitly select the appropriate printf
version using command-line arguments, configuration files, or other such means. It may be necessary to make the compiler include a version of printf-related functions that supports the %f
specifier, or else use some other means of formatting the output. My own preferred approach is to convert the value to a scaled integer (e.g. 100x the desired value) and then write a method which will output digits, least-significant first, and insert a period after outputting some number of digits. Something like:
uint32_t acc;
uint8_t divMod10()
{
uint8_t result = acc % 10;
acc /= 10;
}
// output value in acc using 'digits' digits, with a decimal point shown after dp.
// If dp is greater than 128, don't show decimal point or leading zeroes
// If dp is less than 128 but greater than digits, show leading zeroes
void out_number(uint8_t digits, uint8_t dp)
{
acc = num;
while(digits-- > 0)
{
uint8_t ch = divMod10();
if (ch != 0 || (dp & 128) == 0)
out_lcd(ch + '0');
else
out_lcd(ch);
if (--dp == 0)
out_lcd('.');
}
}
Since LCD modules can be configured to receive data right-to-left, outputting numbers in that form can be a useful simplification. Note that I very seldom use any "printf"-family functions on small microcontrollers, since code like the above is often much more compact.