提交 8ff74d60 编写于 作者: J John Lindgren

Allow UnityPrintFloat() to print a 7th digit.

上级 774da10e
...@@ -258,11 +258,14 @@ void UnityPrintMask(const UNITY_UINT mask, const UNITY_UINT number) ...@@ -258,11 +258,14 @@ void UnityPrintMask(const UNITY_UINT mask, const UNITY_UINT number)
/*-----------------------------------------------*/ /*-----------------------------------------------*/
#ifndef UNITY_EXCLUDE_FLOAT_PRINT #ifndef UNITY_EXCLUDE_FLOAT_PRINT
/* This function prints a floating-point value in a format similar to /*
* printf("%.6g"). It can work with either single- or double-precision, * This function prints a floating-point value in a format similar to
* but for simplicity, it prints only 6 significant digits in either case. * printf("%.7g"). It can work with either single- or double-precision,
* Printing more than 6 digits accurately is hard (at least in the single- * but for simplicity, it prints only 7 significant digits in either case.
* precision case) and isn't attempted here. */ * 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) void UnityPrintFloat(const UNITY_DOUBLE input_number)
{ {
UNITY_DOUBLE number = input_number; UNITY_DOUBLE number = input_number;
...@@ -285,22 +288,42 @@ void UnityPrintFloat(const UNITY_DOUBLE input_number) ...@@ -285,22 +288,42 @@ void UnityPrintFloat(const UNITY_DOUBLE input_number)
UNITY_INT32 n; UNITY_INT32 n;
char buf[16]; char buf[16];
/* scale up or down by powers of 10 */ /*
while (number < 100000.0f / 1e6f) { number *= 1e6f; exponent -= 6; } * Scale up or down by powers of 10. To minimize rounding error,
while (number < 100000.0f) { number *= 10.0f; exponent--; } * start with a factor/divisor of 10^10, which is the largest
while (number > 1000000.0f * 1e6f) { number /= 1e6f; exponent += 6; } * power of 10 that can be represented exactly. Finally, compute
while (number > 1000000.0f) { number /= 10.0f; exponent++; } * (exactly) the remaining power of 10 and perform one more
* multiplication or division.
*/
if(number < 1e6f)
{
UNITY_DOUBLE factor = 1.0f;
while(number < 1e7f / 1e10f) { number *= 1e10f; exponent -= 10; }
while(number * factor < 1e6f) { factor *= 10.0f; exponent--; }
number *= factor;
}
else if(number > 1e7f)
{
UNITY_DOUBLE divisor = 1.0f;
while(number > 1e6f * 1e10f) { number /= 1e10f; exponent += 10; }
while(number / divisor > 1e7f) { divisor *= 10.0f; exponent++; }
number /= divisor;
}
/* round to nearest integer */ /* round to nearest integer */
n = ((UNITY_INT32)(number + number) + 1) / 2; n = ((UNITY_INT32)(number + number) + 1) / 2;
if (n > 999999) if (n > 9999999)
{ {
n = 100000; n = 1000000;
exponent++; exponent++;
} }
/* determine where to place decimal point */ /* determine where to place decimal point */
decimals = (exponent <= 0 && exponent >= -9) ? -exponent : 5; decimals = (exponent <= 0 && exponent >= -10) ? -exponent : 6;
exponent += decimals; exponent += decimals;
/* truncate trailing zeroes after decimal point */ /* truncate trailing zeroes after decimal point */
......
...@@ -4466,46 +4466,48 @@ void testFloatPrinting(void) ...@@ -4466,46 +4466,48 @@ void testFloatPrinting(void)
#if defined(UNITY_EXCLUDE_FLOAT_PRINT) || !defined(USING_OUTPUT_SPY) #if defined(UNITY_EXCLUDE_FLOAT_PRINT) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE(); TEST_IGNORE();
#else #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("0", 0.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.99e-07", 0.000000499f); TEST_ASSERT_EQUAL_PRINT_FLOATING("4.99e-07", 0.000000499f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("5e-07", 0.00000050000005f); TEST_ASSERT_EQUAL_PRINT_FLOATING("5e-07", 0.0000005f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("0.100469", 0.100469499f); TEST_ASSERT_EQUAL_PRINT_FLOATING("0.1004695", 0.1004695f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1", 0.9999995f); /*Rounding to int place*/ 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", 1.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.25", 1.25f); TEST_ASSERT_EQUAL_PRINT_FLOATING("1.25", 1.25f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("7.99999", 7.99999f); /*Not rounding*/ TEST_ASSERT_EQUAL_PRINT_FLOATING("7.999999", 7.999999f); /*Not rounding*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("16.0002", 16.0002f); TEST_ASSERT_EQUAL_PRINT_FLOATING("16.00002", 16.00002f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("16.0004", 16.0004f); TEST_ASSERT_EQUAL_PRINT_FLOATING("16.00004", 16.00004f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("16.0006", 16.0006f); TEST_ASSERT_EQUAL_PRINT_FLOATING("16.00006", 16.00006f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("999999", 999999.0f); /*Last full print integer*/ 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("-0", -0.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-4.99e-07", -0.000000499f); TEST_ASSERT_EQUAL_PRINT_FLOATING("-4.99e-07", -0.000000499f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-5e-07", -0.00000050000005f); TEST_ASSERT_EQUAL_PRINT_FLOATING("-5e-07", -0.0000005f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-0.100469", -0.100469499f); TEST_ASSERT_EQUAL_PRINT_FLOATING("-0.1004695", -0.1004695f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-1", -0.9999995f); /*Rounding to int place*/ 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", -1.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-1.25", -1.25f); TEST_ASSERT_EQUAL_PRINT_FLOATING("-1.25", -1.25f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-7.99999", -7.99999f); /*Not rounding*/ TEST_ASSERT_EQUAL_PRINT_FLOATING("-7.999999", -7.999999f); /*Not rounding*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.0002", -16.0002f); TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.00002", -16.00002f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.0004", -16.0004f); TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.00004", -16.00004f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.0006", -16.0006f); TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.00006", -16.00006f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-999999", -999999.0f); /*Last full print integer*/ TEST_ASSERT_EQUAL_PRINT_FLOATING("-9999999", -9999999.0f); /*Last full print integer*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.29497e+09", 4294967296.0f); TEST_ASSERT_EQUAL_PRINT_FLOATING("4.294967e+09", 4294967296.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("5e+09", 5000000000.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("8e+09", 8.0e+09f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("8.31e+09", 8309999104.0f); TEST_ASSERT_EQUAL_PRINT_FLOATING("8.309999e+09", 8309999104.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1e+10", 1.0e+10f); TEST_ASSERT_EQUAL_PRINT_FLOATING("1e+10", 1.0e+10f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1e+10", 10000000000.0f); TEST_ASSERT_EQUAL_PRINT_FLOATING("1e+10", 10000000000.0f);
/* Some compilers have trouble with inexact float constants, a float cast works generally */ /* Some compilers have trouble with inexact float constants, a float cast works generally */
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.00005e+10", (float)1.000054e+10f); 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.1e+38", (float)1.10000005e+38f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.6353e+10", 1.63529943e+10f); TEST_ASSERT_EQUAL_PRINT_FLOATING("1.635299e+10", 1.63529943e+10f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("3.40282e+38", 3.40282346638e38f); 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("-1e+10", -1.0e+10f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-3.40282e+38", -3.40282346638e38f); TEST_ASSERT_EQUAL_PRINT_FLOATING("-3.402823e+38", -3.40282346638e38f);
#endif #endif
} }
...@@ -4526,27 +4528,43 @@ static void printFloatValue(float f) ...@@ -4526,27 +4528,43 @@ static void printFloatValue(float f)
{ {
char expected[18]; char expected[18];
char expected_lower[18]; char expected_lower[18];
char expected_lower2[18];
char expected_lower3[18];
char expected_higher[18]; char expected_higher[18];
char expected_higher2[18];
char expected_higher3[18];
startPutcharSpy(); startPutcharSpy();
UnityPrintFloat(f); UnityPrintFloat(f);
sprintf(expected, "%.6g", f); sprintf(expected, "%.7g", f);
/* We print all NaN's as "nan", not "-nan" */ /* We print all NaN's as "nan", not "-nan" */
if(strcmp(expected, "-nan") == 0) strcpy(expected, "nan"); if(strcmp(expected, "-nan") == 0) strcpy(expected, "nan");
/* Allow for rounding differences in last digit */ /* Allow for relative error of +/-2.5e-7 */
double lower = (double)f * 0.9999995; double lower = (double)f * 0.99999995;
double higher = (double)f * 1.0000005; double lower2 = (double)f * 0.99999985;
double lower3 = (double)f * 0.99999975;
if (isfinite(lower)) sprintf(expected_lower, "%.6g", lower); else strcpy(expected_lower, expected); double higher = (double)f * 1.00000005;
if (isfinite(higher)) sprintf(expected_higher, "%.6g", higher); else strcpy(expected_higher, expected); double higher2 = (double)f * 1.00000015;
double higher3 = (double)f * 1.00000025;
if(isfinite(lower)) sprintf(expected_lower, "%.7g", lower); else strcpy(expected_lower, expected);
if(isfinite(lower2)) sprintf(expected_lower2, "%.7g", lower2); else strcpy(expected_lower2, expected);
if(isfinite(lower3)) sprintf(expected_lower3, "%.7g", lower3); else strcpy(expected_lower3, expected);
if(isfinite(higher)) sprintf(expected_higher, "%.7g", higher); else strcpy(expected_higher, expected);
if(isfinite(higher2)) sprintf(expected_higher2, "%.7g", higher2); else strcpy(expected_higher2, expected);
if(isfinite(higher3)) sprintf(expected_higher3, "%.7g", higher3); else strcpy(expected_higher3, expected);
if (strcmp(expected, getBufferPutcharSpy()) != 0 && if (strcmp(expected, getBufferPutcharSpy()) != 0 &&
strcmp(expected_lower, getBufferPutcharSpy()) != 0 && strcmp(expected_lower, getBufferPutcharSpy()) != 0 &&
strcmp(expected_higher, getBufferPutcharSpy()) != 0) strcmp(expected_lower2, getBufferPutcharSpy()) != 0 &&
strcmp(expected_lower3, getBufferPutcharSpy()) != 0 &&
strcmp(expected_higher, getBufferPutcharSpy()) != 0 &&
strcmp(expected_higher2, getBufferPutcharSpy()) != 0 &&
strcmp(expected_higher3, getBufferPutcharSpy()) != 0)
{ {
/* Fail with diagnostic printing */ /* Fail with diagnostic printing */
TEST_ASSERT_EQUAL_PRINT_FLOATING(expected, f); TEST_ASSERT_EQUAL_PRINT_FLOATING(expected, f);
...@@ -5252,20 +5270,20 @@ void testDoublePrinting(void) ...@@ -5252,20 +5270,20 @@ void testDoublePrinting(void)
#if defined(UNITY_EXCLUDE_FLOAT_PRINT) || defined(UNITY_EXCLUDE_DOUBLE) || !defined(USING_OUTPUT_SPY) #if defined(UNITY_EXCLUDE_FLOAT_PRINT) || defined(UNITY_EXCLUDE_DOUBLE) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE(); TEST_IGNORE();
#else #else
TEST_ASSERT_EQUAL_PRINT_FLOATING("0.100469", 0.10046949999999999); TEST_ASSERT_EQUAL_PRINT_FLOATING("0.1004695", 0.10046949999999999);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.29497e+09", 4294967295.999999); TEST_ASSERT_EQUAL_PRINT_FLOATING("4.294967e+09", 4294967295.999999);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.29497e+09", 4294967295.9999995); TEST_ASSERT_EQUAL_PRINT_FLOATING("4.294967e+09", 4294967295.9999995);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.29497e+09", 4294967296.0); TEST_ASSERT_EQUAL_PRINT_FLOATING("4.294967e+09", 4294967296.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1e+10", 9999999995.0); TEST_ASSERT_EQUAL_PRINT_FLOATING("1e+10", 9999999995.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("9.0072e+15", 9007199254740990.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("7e+100", 7.0e+100);
TEST_ASSERT_EQUAL_PRINT_FLOATING("3e+200", 3.0e+200); TEST_ASSERT_EQUAL_PRINT_FLOATING("3e+200", 3.0e+200);
TEST_ASSERT_EQUAL_PRINT_FLOATING("9.23457e+300", 9.23456789e+300); TEST_ASSERT_EQUAL_PRINT_FLOATING("9.234568e+300", 9.23456789e+300);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-0.100469", -0.10046949999999999); TEST_ASSERT_EQUAL_PRINT_FLOATING("-0.1004695", -0.10046949999999999);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-4.29497e+09", -4294967295.999999); TEST_ASSERT_EQUAL_PRINT_FLOATING("-4.294967e+09", -4294967295.999999);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-4.29497e+09", -4294967295.9999995); 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("-7e+100", -7.0e+100);
#endif #endif
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册