我正在尝试为添加(以及其他操作)创建溢出检查,而在我为int编写的单元测试和longs工作正常时,我在尝试将其扩展到浮点数时遇到了一些麻烦。该问题的实质在以下代码中表达:
1 #include "gtest/gtest.h"
2 #include <math.h>
3 #include <cmath>
4 #include <cfloat>
5 #include <float.h>
6 #include <limits>
7
8
9 class Test_FloatPfa : public ::testing::Test
10 {
11 public :
12
13 virtual void SetUp(){}
14 virtual void TearDown(){}
15 };
16
17
18 ///////////////////////////////////Basic operator tests above, overflow tests below////////////////
19
20 TEST_F(Test_FloatPfa, checking_for_FLOAT_sum_overflow)
21 {
22 float numberOne = std::numeric_limits<float>::max();
23 float numberTwo = 1.0;
24 ASSERT_TRUE(numberTwo > numberOne - std::numeric_limits<float>::max());
25 }
26
27 TEST_F(Test_FloatPfa, checking_for_FLOAT_sum_overflow2)
28 {
29
30 float number1 = 1.0;
31 float number2 = std::numeric_limits<float>::max();
32
33 ASSERT_EQ ( number2, std::numeric_limits<float>::max() );
34 printf("number1, number2 and limit -1 is: %f \n, %f \n, %f \n",number1, number2, std::numeric_limits<float>::max() -1);
35 ASSERT_TRUE (number2 > std::numeric_limits<float>::max() - number1 );
36 }
37
38
39
提供以下输出:
Running main() from gtest_main.cc
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from Test_FloatPfa
[ RUN ] Test_FloatPfa.checking_for_FLOAT_sum_overflow
[ OK ] Test_FloatPfa.checking_for_FLOAT_sum_overflow (0 ms)
[ RUN ] Test_FloatPfa.checking_for_FLOAT_sum_overflow2
number1, number2 and limit -1 is: 1.000000
, 340282346638528859811704183484516925440.000000
, 340282346638528859811704183484516925440.000000
/home/adam/Projects/git/pfa-cpp-lib/PFALib/test/TEst_for_SO.cpp:35: Failure
Value of: number2 > std::numeric_limits<float>::max() - number1
Actual: false
Expected: true
[ FAILED ] Test_FloatPfa.checking_for_FLOAT_sum_overflow2 (0 ms)
[----------] 2 tests from Test_FloatPfa (0 ms total)
[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (1 ms total)
[ PASSED ] 1 test.
[ FAILED ] 1 test, listed below:
[ FAILED ] Test_FloatPfa.checking_for_FLOAT_sum_overflow2
1 FAILED TEST
它似乎无法识别从最大浮点值中减去一个,导致不等式计算为false。 write语句确认最大值减1不会被评估为小于最大值本身。
提前感谢您提供的任何见解。
答案 0 :(得分:0)
您的程序运行正常,浮点值没有溢出。因为你的第一个数字四舍五入为零。
尝试将第一个数字设置为1e30
也尝试编写代码:
(1e21 + 1e0)-1e21 = 0但是1e21-1e21 + 1e0 = 1e0
答案 1 :(得分:0)
IEEE754单精度(32位)浮点类型存储6到9个有效精度数字的数字。 要准确地减去1来进行预期的计算,需要39个有效的准确数字。这远远超出了可能的范围。
简而言之,这是因为单个精度浮点值存储在3个部分中:
浮点数的最大值是 -
340282346638528859811704183484516925440
with sign=0, biased exponent=254, mantissa=8388607
and hexadecimal representation 0x7F7FFFFF
可以表示的下一个最高数字将使尾数减少1.这给出了 -
340282326356119256160033759537265639424
with sign=0, exponent=254, mantissa=8388606
and hexadecimal representation 0x7F7FFFFE
浮点类型的操作不像整数那样环绕。相反,他们明确地为超出范围的结果产生无限或非数字的“NaN”值。
在这种情况下,你为什么不进行有问题的操作并检查它是否没有溢出std::isfinite
?
有关单精度浮点表示的更多基础知识,请参阅"Single-precision floating-point format"。
但是,如果您真的想了解浮点数学的工作原理及其对数字编程的影响,那么您最好不要阅读David Goldberg撰写的"What Every Computer Scientist Should Know About Floating-Point Arithmetic"。