Open MalcolmBoura opened 2 years ago
You've reported this on the AVR core, whose code does not really need to be portable. In particular, long is always 32-bit and float is identical to double there. You are right that using named constants over magic numbers is a good idea.
However, the ArduinoCore-API repo has this exact same code and that repo is intended to be portable (also intended to replace the AVR-specific code in the AVR repository), so I agree that this should be fixed there.
I will transfer this issue to the ArduinoCore-API repo, where I think it would be better placed.
I have not looked at the implementation in detail, I'll leave that to others.
It has occurred to me that the conversion from the literal constant to float in order to carry out the comparison may result in a value a few hundred lower than MAX_INT being needed. All very messy as it depends on how that is implemented. I don't recall it being defined anywhere. Anyway, it would be better to use something human friendly like 1E9.
A function named printFloat that prints a double is unfortunate naming!
https://github.com/arduino/ArduinoCore-avr/blob/2ff00ae7d4e85fa422b7918ee12baf56a1f3006e/cores/arduino/Print.cpp#L229
The comment indicates a problem. It works but empirical constants are not good practice!
The range check is needed in order to prevent the integer part of the float overflowing in https://github.com/arduino/ArduinoCore-avr/blob/2ff00ae7d4e85fa422b7918ee12baf56a1f3006e/cores/arduino/Print.cpp#L247 unsigned long is not necessarily 32 bits so the numeric literal is non-portable. The constant is actually the unsigned long equivalent of INT_MAX - 1. (The -1 is to allow for rounding but further thought needed to be certain of that).
I have a fix which avoids the need for int_part so the problem no longer arises. It also makes the implementation of %g and %e formats relatively trivial.
printFloat(float f, struct PrintOptions *options)
I would welcome feedback on the various options before I do anything further.