-
Notifications
You must be signed in to change notification settings - Fork 13.3k
dtostrf/Print(float) inconsistent value/methods, downstream use #7073
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
I would vote for NOT using sprint as the only solution. The reason why, (s)printf implementation is rather large body of code, and one common plan to reduce code size is to avoid it and use the lower level conversion methods, like dtostrf; which now would be a useless solution. |
Would using newlib method in Print and String, but leaving dtostrf as-is be reasonable? When using dtostrf we get what we get. When using print / string there is a correct result, that also can be optionally removed from the build Just comparing local test builds with the master:
|
Good info in the build sizes, @mcspr
I hate keeping the broken bits in, but pragmatically we can isolate it so only folks who explicitly use it for memory savings. It is still kind of a breaking change that way, though. |
Internal discussion has ended up liking option 5) the best. Would that pass muster for you, @Makuna @mcspr , anyone else? If you call dtostrf() you get what you get (we revert to the code that was there, so some rounding issues but close enough for most purposes). If you call Print(float,nnn) you get sprintf("%f"). If you have disabled print_float, then obviously Print(float,nnn) isn't going to work. |
Reasonable compromise. |
Sure, but I am starting to think about subtle bugs that it may cause :/ And I will need to scan some rogue String += with floats in the code... What I am all for is having a way to strip size, I just wonder if that is the correct way. Also, since Tasmota script was linked, cc @arendst HEAD, removed strip-float.py -> 628656 bytes
@earlephilhower Did you mean something like this? --- a/cores/esp8266/core_esp8266_noniso.cpp
+++ b/cores/esp8266/core_esp8266_noniso.cpp
@@ -41,6 +41,7 @@ char* ultoa(unsigned long value, char* result, int base) {
}
char * dtostrf(double number, signed char width, unsigned char prec, char *s) {
+ asm(".global _printf_float");
char fmt[32];
sprintf(fmt, "%%%d.%df", width, prec);
sprintf(s, fmt, number); Implying removing -u _printf_float from ld flags |
Just my two cents. If using the Stage version and compiling Tasmota with Zigbee and strip-floats applied the resulting compiled size is 545684. With strip-floats removed it becomes 560716. This is consistent with earlier findings on different core versions; adding floats always added over 10k of code. |
#7068 removed two slightly different (and both slightly wrong) implementations of
double
toASCII string
inPrint::print(float)
anddtostrf
(a non-std. AVR C addition AFAICT) and replaced it with a call to newlib'ssprintf(%f)
which is known good.Unfortunately, as @mcspr noted, there are folks who are building the core w/o float-printf support (
printf_float
in platform.txt), so the above PR will end up borking their output.The main question now is what is the right thing to do in this case. I suggest it's one of the following:
FWIW, looking at the AVC-LIBC implementation, it is closest in logic to number 2 above. They go down to the binary FP level and extract exponents and mantissas (as the AVR ASM level) and work with those parts to actually generate strings.
Any opinions from downstream?
The text was updated successfully, but these errors were encountered: