I am looking for an elegant way to always print the same number of digits of a float for display purposes. For example, I want to print 5 digits of the incoming floats, so if the incoming float is 1.23654, I want to print “1.236”. But it should also work if the incoming float is larger or smaller; if the incoming float is 11.23456, it should print “11.23” and if the incoming float is 0.01233456 it should print “0.012”
Do you know how to achieve it? sprintf does not work with floats, and dtostrf() allows you to force the minimum number of digits, not the maximum…
Yes, I did. The problem with Serial. print (float, 5) is that it prints the float with 5 digits after the "." so, if the float is greater than 1, the total number of digits will be greater than 5.
And it should work for any float (big one, as for the small one). I can always check if the float is greater than 1 and smaller than 10 and so on, but I'll call it rather rathe "force brut."
It does *. You don't mention how you came to that conclusion, but the specifier needs to be 'f' for floating point numbers, e.g. %02.3f (two zero padded digits before and three after the decimal) rather than e.g %05d which would be for integer digits. However, the specifier would need to be manipulated somehow, or several if ... then sprintf() statements for each count of digits after the decimal point.
With Serial.println(myfloat, 5), the '5' can also be a computed integer variable. It does not have to be a literal.
Nevertheless, the solution in post #7 seems rather more elegant.
I am currently working on a project with floats that it seems to work fine with, however the board has an RP2040 rather than an Atmel chip. Sounds like I may need to test it with an ATmega....
Try this sketch on UNO R3, which takes input float number as string from Serial Monitor:
char myData[20];
void setup() {
Serial.begin(9600);
}
void loop() {
byte n = Serial.available();
if(n != 0)
{
byte m = Serial.readBytesUntil('\n', myData, sizeof myData - 1);
myData[m] = '\0';
float myFloat = atof(myData);
byte p = getIntegerDigitCount(myFloat);
Serial.println(myFloat, 4-p); //p = number of digits in the integr part of float
}
}
int getIntegerDigitCount(float val) {
val = fabsf(val); // Work with absolute value to handle negatives
if (val < 1.0f) {
return 1; // "0.x" has 1 digit in its integer part ('0')
}
return (int)floor(log10(val)) + 1;
}