mirror of
https://github.com/ThrowTheSwitch/Unity.git
synced 2025-06-26 03:17:59 +08:00
Improve accuracy of UnityPrintFloat() for common cases.
This commit is contained in:
21
src/unity.c
21
src/unity.c
@ -283,9 +283,9 @@ void UnityPrintFloat(const UNITY_DOUBLE input_number)
|
|||||||
else if (isinf(number)) UnityPrint("inf");
|
else if (isinf(number)) UnityPrint("inf");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
UNITY_INT32 n = 0;
|
||||||
int exponent = 0;
|
int exponent = 0;
|
||||||
int decimals, digits;
|
int decimals, digits;
|
||||||
UNITY_INT32 n;
|
|
||||||
char buf[16];
|
char buf[16];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -295,7 +295,7 @@ void UnityPrintFloat(const UNITY_DOUBLE input_number)
|
|||||||
* (exactly) the remaining power of 10 and perform one more
|
* (exactly) the remaining power of 10 and perform one more
|
||||||
* multiplication or division.
|
* multiplication or division.
|
||||||
*/
|
*/
|
||||||
if(number < 1e6f)
|
if(number < 1.0f)
|
||||||
{
|
{
|
||||||
UNITY_DOUBLE factor = 1.0f;
|
UNITY_DOUBLE factor = 1.0f;
|
||||||
|
|
||||||
@ -313,9 +313,24 @@ void UnityPrintFloat(const UNITY_DOUBLE input_number)
|
|||||||
|
|
||||||
number /= divisor;
|
number /= divisor;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* In this range, we can split off the integer part before
|
||||||
|
* doing any multiplications. This reduces rounding error by
|
||||||
|
* freeing up significant bits in the fractional part.
|
||||||
|
*/
|
||||||
|
UNITY_DOUBLE factor = 1.0f;
|
||||||
|
n = (UNITY_INT32)number;
|
||||||
|
number -= (UNITY_DOUBLE)n;
|
||||||
|
|
||||||
|
while(n < 1000000) { n *= 10; factor *= 10.0f; exponent--; }
|
||||||
|
|
||||||
|
number *= factor;
|
||||||
|
}
|
||||||
|
|
||||||
/* round to nearest integer */
|
/* round to nearest integer */
|
||||||
n = ((UNITY_INT32)(number + number) + 1) / 2;
|
n += ((UNITY_INT32)(number + number) + 1) / 2;
|
||||||
if (n > 9999999)
|
if (n > 9999999)
|
||||||
{
|
{
|
||||||
n = 1000000;
|
n = 1000000;
|
||||||
|
@ -4543,20 +4543,33 @@ static void printFloatValue(float 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 relative error of +/-2.5e-7 */
|
strcpy(expected_lower, expected);
|
||||||
double lower = (double)f * 0.99999995;
|
strcpy(expected_lower2, expected);
|
||||||
double lower2 = (double)f * 0.99999985;
|
strcpy(expected_lower3, expected);
|
||||||
double lower3 = (double)f * 0.99999975;
|
strcpy(expected_higher, expected);
|
||||||
double higher = (double)f * 1.00000005;
|
strcpy(expected_higher2, expected);
|
||||||
double higher2 = (double)f * 1.00000015;
|
strcpy(expected_higher3, expected);
|
||||||
double higher3 = (double)f * 1.00000025;
|
|
||||||
|
|
||||||
if(isfinite(lower)) sprintf(expected_lower, "%.7g", lower); else strcpy(expected_lower, expected);
|
/* Allow for rounding differences in the last digit */
|
||||||
if(isfinite(lower2)) sprintf(expected_lower2, "%.7g", lower2); else strcpy(expected_lower2, expected);
|
double lower = (double)f * 0.99999995;
|
||||||
if(isfinite(lower3)) sprintf(expected_lower3, "%.7g", lower3); else strcpy(expected_lower3, expected);
|
double higher = (double)f * 1.00000005;
|
||||||
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(lower)) sprintf(expected_lower, "%.7g", lower);
|
||||||
if(isfinite(higher3)) sprintf(expected_higher3, "%.7g", higher3); else strcpy(expected_higher3, expected);
|
if(isfinite(higher)) sprintf(expected_higher, "%.7g", higher);
|
||||||
|
|
||||||
|
/* Outside [1,10000000] allow for relative error of +/-2.5e-7 */
|
||||||
|
if(f < 1.0 || f > 10000000)
|
||||||
|
{
|
||||||
|
double lower2 = (double)f * 0.99999985;
|
||||||
|
double lower3 = (double)f * 0.99999975;
|
||||||
|
double higher2 = (double)f * 1.00000015;
|
||||||
|
double higher3 = (double)f * 1.00000025;
|
||||||
|
|
||||||
|
if(isfinite(lower2)) sprintf(expected_lower2, "%.7g", lower2);
|
||||||
|
if(isfinite(lower3)) sprintf(expected_lower3, "%.7g", lower3);
|
||||||
|
if(isfinite(higher2)) sprintf(expected_higher2, "%.7g", higher2);
|
||||||
|
if(isfinite(higher3)) sprintf(expected_higher3, "%.7g", higher3);
|
||||||
|
}
|
||||||
|
|
||||||
if (strcmp(expected, getBufferPutcharSpy()) != 0 &&
|
if (strcmp(expected, getBufferPutcharSpy()) != 0 &&
|
||||||
strcmp(expected_lower, getBufferPutcharSpy()) != 0 &&
|
strcmp(expected_lower, getBufferPutcharSpy()) != 0 &&
|
||||||
|
Reference in New Issue
Block a user