[Poincare] Changed ConvertFloatToText to prevent conversion error

We now compute the value of the mantissa in double (instead of float)
to limit conversion error occuring for big numbers.

Change-Id: Ia61c052f0bc4a9196c53e2c7900eb48e3343d39c
This commit is contained in:
Arthur Camouseigt
2020-06-22 11:51:29 +02:00
committed by Émilie Feral
parent 776edd4dd8
commit 082f9819e9
2 changed files with 17 additions and 4 deletions

View File

@@ -207,10 +207,22 @@ PrintFloat::TextLengths PrintFloat::ConvertFloatToTextPrivate(T f, char * buffer
/* Part I: Mantissa */
// Compute mantissa
T unroundedMantissa = f * std::pow((T)10.0, (T)(numberOfSignificantDigits - 1 - exponentInBase10));
/* Compute mantissa
* We compute the unroundedMantissa using doubles to limit approximation errors.
* Previously when computing with floats : 0.000600000028 * 10^10 = 6000000.28
* was rounded into 6000000.5 because of the conversion error
* Mantissa was the 6000001 instead of 6000000.
* As a result, 0.0006 was displayed as 0.0006000001
* With doubles, 0.000600000028 * 10^10 = 6000000.2849...
* This value is then rounded into mantissa = 6000000 which yields a proper
* display of 0.0006 */
double unroundedMantissa = static_cast<double>(f) * std::pow(10.0, (double)(numberOfSignificantDigits - 1 - exponentInBase10));
// Round mantissa to get the right number of significant digits
T mantissa = std::round(unroundedMantissa);
double mantissa = std::round(unroundedMantissa);
/* Since no problem of approximation was detected from using potential float
* (instead of double) in the rest of the code, we decided to leave it like
* this */
/* If (numberOfSignificantDigits - 1 - exponentInBase10) is too big (or too
* small), mantissa is now inf. We handle this case by using logarithm
@@ -225,7 +237,7 @@ PrintFloat::TextLengths PrintFloat::ConvertFloatToTextPrivate(T f, char * buffer
* "exponentBase10(unroundedMantissa) != exponentBase10(mantissa)",
* However, unroundedMantissa can have a different exponent than expected
* (ex: f = 1E13, unroundedMantissa = 99999999.99 and mantissa = 1000000000) */
if (f != 0 && IEEE754<T>::exponentBase10(mantissa) - exponentInBase10 != numberOfSignificantDigits - 1 - exponentInBase10) {
if (f != 0 && IEEE754<double>::exponentBase10(mantissa) - exponentInBase10 != numberOfSignificantDigits - 1 - exponentInBase10) {
exponentInBase10++;
}

View File

@@ -30,6 +30,7 @@ QUIZ_CASE(assert_print_floats) {
assert_float_prints_to(123.456f, "1.23456ᴇ2", ScientificMode, 7);
assert_float_prints_to(123.456f, "123.456", DecimalMode, 7);
assert_float_prints_to(123.456f, "123.456", EngineeringMode, 7);
assert_float_prints_to(0.0006f, "0.0006", DecimalMode, 7);
assert_float_prints_to(123.456, "1.23456ᴇ2", ScientificMode, 14);
assert_float_prints_to(123.456, "123.456", DecimalMode, 14);
assert_float_prints_to(123.456, "123.456", EngineeringMode, 14);