-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Proposed update for the printFloat code of print.cpp #247
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Code has been improved and tested. Support for -infinity and both SCI and ENG formatting for floating point numbers. Used it for several weeks with no new problems. Code see zipfile attached to - http://forum.arduino.cc/index.php?topic=166041.msg1241170#msg1241170 - |
This issue is still present 4 years later, it would be nice to have an explanation as to why there are certain limitations embedded in the print function, and these in particular:
Clearly the code following these lines has some limitations which justify these guards, however it is unclear the reason why it was decided to keep this undocumented behaviour instead of fixing the code in the official repository. If there is no plan to fix this issue in the official upstream repository, the documentation (also this) should be updated to reflect the actual implementation and warn users about this inherent limitation, since it is a totally counter-intuitive behaviour. |
Old thread woke up :) probably too busy with new features as that is more fun? looking at the printFloat code above I would now remove the abs() and probably replace the float division by a multiply to speed it up a bit. size_t Print::printFloat(double number, uint8_t digits)
{
size_t n = 0;
int exponent = 0;
if (isnan(number)) return print("nan");
if (isinf(number)) return print("inf");
// Handle negative numbers
if (number < 0.0)
{
n += print('-');
number = -number;
}
if (number > 1000000000.0)
{
while (number > 10.0)
{
number /= 10.0; // number *= 0.1;
exponent++;
}
}
else if (number < 0.001)
{
while (number < 1.0)
{
number *= 10.0;
exponent--;
}
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
for (uint8_t i = 0; i < digits; ++i)
rounding /= 10.0; // number *= 0.1
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
n += print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits > 0) {
n += print(".");
}
// Extract digits from the remainder one at a time
while (digits-- > 0)
{
remainder *= 10.0;
int toPrint = int(remainder);
n += print(toPrint);
remainder -= toPrint;
}
if (exponent != 0)
{
n += print('E');
if (exponent > 0) n += print('+');
n += print(exponent);
}
return n;
} |
@RobTillaart
Corrected by :
|
you're 100% right! |
Created my own lib to solve this - https://github.com/RobTillaart/printHelpers |
The printing of floats has an error in it as it prints floats larger than maxlong as "ovf" or overflow as the current printFloat() does not support scientific notation.
In - http://forum.arduino.cc/index.php?topic=166041.0 - I discuss / propose a change to support printing of floats larger than maxlong and printing of very small floats that otherwise would be rounded to 0. On the forum is also a small test sketch.
The interface of print() and println() is not changed so the user cannot force E notation, that is for the future, one step at the time ;)
Rob.
Code snippet
The text was updated successfully, but these errors were encountered: