C++浮点减法似乎没有发生

C++ floating point subtraction doesn't appear to occur

本文关键字:浮点减 C++      更新时间:2023-10-16

我正在尝试创建额外的溢出检查(在其他操作中),而我为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。写声明证实,最大值减去一个人的评估不小于最大值本身。

事先感谢您可能拥有的任何见解。

您的程序为正常工作,没有浮点值的溢出。因为您的第一个数字四舍五入为零。

尝试将第一个数字设置为1E30

也尝试编码以下编码:

(1E21 1E0)-1E21 = 0,但是1E21-1E21 1E0 = 1E0

IEEE754单个精度(32位)浮点类型存储数量在6到9个重要的精度数字之间。要准确地减去1个要计算,将需要39个重要的准确性数字。这超出了可能的范围。

简而言之,这是因为单个精度浮点值存储在3个部分中:

  • 一个1位标志,
  • 8位有偏见的指数和
  • 23位Mantissa。

浮子的最大值是 -

340282346638528859811704183484516925440 
with sign=0, biased exponent=254, mantissa=8388607
and hexadecimal representation 0x7F7FFFFF

可以代表的下一个最高数字将使mantsa减少1。这给出了 -

340282326356119256160033759537265639424 
with sign=0, exponent=254, mantissa=8388606
and hexadecimal representation 0x7F7FFFFE

对浮点类型的操作不会像整数那样缠绕。取而代

是这种情况,为什么不只是进行有问题的操作,并检查它尚未与std::isfinite溢出?


有关单个精确浮点表示的更多基础知识,请参见"单精度浮点格式"。

但是,如果您真的想了解浮点数学如何工作的细节以及对数字编程的含义,那么您可以做得更好,而不是阅读"每个计算机科学家对浮点算术的了解",David Goldberg <<<<<<<<<<<<<<<<<。/p>