Print 9 digits if we have double precision capability.

This commit is contained in:
John Lindgren
2017-11-07 22:44:59 -05:00
parent 74ba70283a
commit 2d4e32cda1
2 changed files with 129 additions and 58 deletions
src
test/tests

@ -260,14 +260,23 @@ void UnityPrintMask(const UNITY_UINT mask, const UNITY_UINT number)
#ifndef UNITY_EXCLUDE_FLOAT_PRINT
/*
* This function prints a floating-point value in a format similar to
* printf("%.7g"). It can work with either single- or double-precision,
* but for simplicity, it prints only 7 significant digits in either case.
* The 7th digit won't always be totally correct in single-precision
* operation (for that level of accuracy, a more complicated algorithm
* would be needed).
* printf("%.7g") on a single-precision machine or printf("%.9g") on a
* double-precision machine. The 7th digit won't always be totally correct
* in single-precision operation (for that level of accuracy, a more
* complicated algorithm would be needed).
*/
void UnityPrintFloat(const UNITY_DOUBLE input_number)
{
#ifdef UNITY_INCLUDE_DOUBLE
static const int sig_digits = 9;
static const UNITY_INT32 min_scaled = 100000000;
static const UNITY_INT32 max_scaled = 1000000000;
#else
static const int sig_digits = 7;
static const UNITY_INT32 min_scaled = 1000000;
static const UNITY_INT32 max_scaled = 10000000;
#endif
UNITY_DOUBLE number = input_number;
/* print minus sign (including for negative zero) */
@ -295,21 +304,21 @@ void UnityPrintFloat(const UNITY_DOUBLE input_number)
* (exactly) the remaining power of 10 and perform one more
* multiplication or division.
*/
if(number < 1.0f)
if (number < 1.0f)
{
UNITY_DOUBLE factor = 1.0f;
while(number < 1e7f / 1e10f) { number *= 1e10f; exponent -= 10; }
while(number * factor < 1e6f) { factor *= 10.0f; exponent--; }
while (number < (UNITY_DOUBLE)max_scaled / 1e10f) { number *= 1e10f; exponent -= 10; }
while (number * factor < (UNITY_DOUBLE)min_scaled) { factor *= 10.0f; exponent--; }
number *= factor;
}
else if(number > 1e7f)
else if (number > (UNITY_DOUBLE)max_scaled)
{
UNITY_DOUBLE divisor = 1.0f;
while(number > 1e6f * 1e10f) { number /= 1e10f; exponent += 10; }
while(number / divisor > 1e7f) { divisor *= 10.0f; exponent++; }
while (number > (UNITY_DOUBLE)min_scaled * 1e10f) { number /= 1e10f; exponent += 10; }
while (number / divisor > (UNITY_DOUBLE)max_scaled) { divisor *= 10.0f; exponent++; }
number /= divisor;
}
@ -324,21 +333,21 @@ void UnityPrintFloat(const UNITY_DOUBLE input_number)
n = (UNITY_INT32)number;
number -= (UNITY_DOUBLE)n;
while(n < 1000000) { n *= 10; factor *= 10.0f; exponent--; }
while (n < min_scaled) { n *= 10; factor *= 10.0f; exponent--; }
number *= factor;
}
/* round to nearest integer */
n += ((UNITY_INT32)(number + number) + 1) / 2;
if (n > 9999999)
if (n >= max_scaled)
{
n = 1000000;
n = min_scaled;
exponent++;
}
/* determine where to place decimal point */
decimals = (exponent <= 0 && exponent >= -10) ? -exponent : 6;
decimals = (exponent <= 0 && exponent >= -(sig_digits + 3)) ? -exponent : (sig_digits - 1);
exponent += decimals;
/* truncate trailing zeroes after decimal point */

@ -4463,38 +4463,37 @@ void testNotEqualFloatEachEqualLengthZero(void)
void testFloatPrinting(void)
{
#if defined(UNITY_EXCLUDE_FLOAT_PRINT) || !defined(USING_OUTPUT_SPY)
#if defined(UNITY_EXCLUDE_FLOAT_PRINT) || defined(UNITY_INCLUDE_DOUBLE) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE();
#else
/* Some failures are expected due to differences in the last digit
* if UnityPrintFloat uses single-precision calculations. */
TEST_ASSERT_EQUAL_PRINT_FLOATING("0", 0.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.99e-07", 0.000000499f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("5e-07", 0.0000005f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("0.1004695", 0.1004695f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("2", 1.9999995f); /*Rounding to int place*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("1", 1.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.25", 1.25f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("7.999999", 7.999999f); /*Not rounding*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("16.00002", 16.00002f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("16.00004", 16.00004f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("16.00006", 16.00006f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("9999999", 9999999.0f); /*Last full print integer*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("0", 0.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.99e-07", 0.000000499f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("5.000001e-07", 0.00000050000005f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("0.1004695", 0.100469499f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("2", 1.9999995f); /*Rounding to int place*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("1", 1.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.25", 1.25f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("7.999999", 7.999999f); /*Not rounding*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("16.00002", 16.00002f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("16.00004", 16.00004f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("16.00006", 16.00006f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("9999999", 9999999.0f); /*Last full print integer*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("-0", -0.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-4.99e-07", -0.000000499f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-5e-07", -0.0000005f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-0.1004695", -0.1004695f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-2", -1.9999995f); /*Rounding to int place*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("-1", -1.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-1.25", -1.25f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-7.999999", -7.999999f); /*Not rounding*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.00002", -16.00002f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.00004", -16.00004f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.00006", -16.00006f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-9999999", -9999999.0f); /*Last full print integer*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("-0", -0.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-4.99e-07", -0.000000499f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-5.000001e-07", -0.00000050000005f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-0.1004695", -0.100469499f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-2", -1.9999995f); /*Rounding to int place*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("-1", -1.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-1.25", -1.25f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-7.999999", -7.999999f); /*Not rounding*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.00002", -16.00002f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.00004", -16.00004f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.00006", -16.00006f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-9999999", -9999999.0f); /*Last full print integer*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.294967e+09", 4294967296.0f);
/* Fails, prints "4.294968e+09" due to FP math imprecision
* TEST_ASSERT_EQUAL_PRINT_FLOATING("4.294967e+09", 4294967296.0f); */
TEST_ASSERT_EQUAL_PRINT_FLOATING("5e+09", 5000000000.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("8e+09", 8.0e+09f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("8.309999e+09", 8309999104.0f);
@ -4504,10 +4503,12 @@ void testFloatPrinting(void)
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.000055e+10", (float)1.000055e+10f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.1e+38", (float)1.10000005e+38f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.635299e+10", 1.63529943e+10f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("3.402823e+38", 3.40282346638e38f);
/* Fails, prints "3.402824e+38" due to FP math imprecision
* TEST_ASSERT_EQUAL_PRINT_FLOATING("3.402823e+38", 3.40282346638e38f); */
TEST_ASSERT_EQUAL_PRINT_FLOATING("-1e+10", -1.0e+10f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-3.402823e+38", -3.40282346638e38f);
/* Fails, prints "-3.402824e+38" due to FP math imprecision
* TEST_ASSERT_EQUAL_PRINT_FLOATING("-3.402823e+38", -3.40282346638e38f); */
#endif
}
@ -4524,6 +4525,41 @@ void testFloatPrintingInfinityAndNaN(void)
}
#if defined(UNITY_TEST_ALL_FLOATS_PRINT_OK) && defined(USING_OUTPUT_SPY)
#ifdef UNITY_INCLUDE_DOUBLE
static void printFloatValue(float f)
{
char expected[18];
char expected_lower[18];
char expected_higher[18];
startPutcharSpy();
UnityPrintFloat(f);
sprintf(expected, "%.9g", f);
/* We print all NaN's as "nan", not "-nan" */
if(strcmp(expected, "-nan") == 0) strcpy(expected, "nan");
strcpy(expected_lower, expected);
strcpy(expected_higher, expected);
/* Allow for rounding differences in the last digit */
double lower = (double)f * 0.9999999995;
double higher = (double)f * 1.0000000005;
if(isfinite(lower)) sprintf(expected_lower, "%.9g", lower);
if(isfinite(higher)) sprintf(expected_higher, "%.9g", higher);
if (strcmp(expected, getBufferPutcharSpy()) != 0 &&
strcmp(expected_lower, getBufferPutcharSpy()) != 0 &&
strcmp(expected_higher, getBufferPutcharSpy()) != 0)
{
/* Fail with diagnostic printing */
TEST_ASSERT_EQUAL_PRINT_FLOATING(expected, f);
}
}
#else
static void printFloatValue(float f)
{
char expected[18];
@ -4584,6 +4620,7 @@ static void printFloatValue(float f)
}
}
#endif
#endif
void testFloatPrintingRandomSamples(void)
{
@ -5283,20 +5320,45 @@ void testDoublePrinting(void)
#if defined(UNITY_EXCLUDE_FLOAT_PRINT) || defined(UNITY_EXCLUDE_DOUBLE) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE();
#else
TEST_ASSERT_EQUAL_PRINT_FLOATING("0.1004695", 0.10046949999999999);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.294967e+09", 4294967295.999999);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.294967e+09", 4294967295.9999995);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.294967e+09", 4294967296.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1e+10", 9999999995.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("9.007199e+15", 9007199254740990.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("7e+100", 7.0e+100);
TEST_ASSERT_EQUAL_PRINT_FLOATING("3e+200", 3.0e+200);
TEST_ASSERT_EQUAL_PRINT_FLOATING("9.234568e+300", 9.23456789e+300);
TEST_ASSERT_EQUAL_PRINT_FLOATING("0", 0.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.99e-07", 0.000000499);
TEST_ASSERT_EQUAL_PRINT_FLOATING("5.0000005e-07", 0.00000050000005);
TEST_ASSERT_EQUAL_PRINT_FLOATING("0.100469499", 0.100469499);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1", 0.9999999995); /*Rounding to int place*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("1", 1.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.25", 1.25);
TEST_ASSERT_EQUAL_PRINT_FLOATING("7.99999999", 7.99999999); /*Not rounding*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("16.0000002", 16.0000002);
TEST_ASSERT_EQUAL_PRINT_FLOATING("16.0000004", 16.0000004);
TEST_ASSERT_EQUAL_PRINT_FLOATING("16.0000006", 16.0000006);
TEST_ASSERT_EQUAL_PRINT_FLOATING("999999999", 999999999.0); /*Last full print integer*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("-0.1004695", -0.10046949999999999);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-4.294967e+09", -4294967295.999999);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-4.294967e+09", -4294967295.9999995);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-7e+100", -7.0e+100);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-0", -0.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-4.99e-07", -0.000000499);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-5.0000005e-07", -0.00000050000005);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-0.100469499", -0.100469499);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-1", -0.9999999995); /*Rounding to int place*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("-1", -1.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-1.25", -1.25);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-7.99999999", -7.99999999); /*Not rounding*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.0000002", -16.0000002);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.0000004", -16.0000004);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.0000006", -16.0000006);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-999999999", -999999999.0); /*Last full print integer*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("0.1004695", 0.10046949999999999);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.2949673e+09", 4294967295.9);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.2949673e+09", 4294967296.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1e+10", 9999999995.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("9.00719925e+15", 9007199254740990.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("7e+100", 7.0e+100);
TEST_ASSERT_EQUAL_PRINT_FLOATING("3e+200", 3.0e+200);
TEST_ASSERT_EQUAL_PRINT_FLOATING("9.23456789e+300", 9.23456789e+300);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-0.1004695", -0.10046949999999999);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-4.2949673e+09", -4294967295.9);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-4.2949673e+09", -4294967296.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-7e+100", -7.0e+100);
#endif
}