找出由整数除法引起的数值误差

时间:2011-05-20 19:46:05

标签: c++ integer-division

是否有g ++警告或其他工具可以识别整数除法(截断为零)?我有成千上万行代码进行计算,不可避免地会出现数值错误,这通常是由于需要定位的“float = int / int”。我需要一种合理的方法来找到它们。

6 个答案:

答案 0 :(得分:2)

尝试-Wconversion

来自gcc的手册页:

  

警告可能的隐式转换   改变一个价值。这包括   实数和整数之间的转换,   比如“abs(x)”,当“x”是“double”时;   签名和签名之间的转换   无符号的,如“unsigned ui = -1”;和   转换为较小的类型,例如   “sqrtf(M_PI)”。不要警告   显式转换,如“abs((int)x)”   和“ui =(无符号)-1”,或者如果   转换不会更改值   比如“abs(2.0)”。警告   签名和签名之间的转换   无符号整数可以被禁用   使用-Wno-sign-conversion。

     

对于C ++,也会警告转换   “NULL”和非指针类型之间;   令人困惑的重载决议   用户定义的转换;和   永远不会使用某种类型的转化   转换运算符:转换为   “void”,同一类型,基类或   对它们的引用。警告   签名和签名之间的转换   无符号整数被禁用   除非是C ++中的默认值   -Wsign-conversion明确启用。

对于以下示例程序(test.cpp),我收到错误test.cpp: In function ‘int main()’: test.cpp:7: warning: conversion to ‘float’ from ‘int’ may alter its value

#include <iostream>

int main()
{
    int a = 2;
    int b = 3;
    float f = a / b;

    std::cout << f;

    return 0;
}

答案 1 :(得分:2)

我很难调用这些数字错误。您要求进行整数计算,并获得整数计算的正确数字。如果这些数字不可接受,那么请求浮点计算:

int x = 3;
int y = 10;

int z = x / y;

// "1." is the same thing as "1.0", you may want to read up on
// "the usual arithmetic conversions."  You could add some
// parentheses here, but they aren't needed for this specific
// statement.
double zz = 1. * x / y;

答案 2 :(得分:1)

答案 3 :(得分:1)

备注-Wconversiongcc

将浮点变量的类型从float更改为double会使警告消失:

$ cat 'file.cpp'

#include <iostream>

int main()
{
   int a = 2;
   int b = 3;
   double f = a / b;

   std::cout << f;
}

使用$ g++-4.7 -Wconversion 'file.cpp'进行编译不会返回任何警告($ clang++ -Weverything 'file.cpp')。

说明:

由于完全有效的整数算术而未返回使用类型float时的警告,但由于float无法存储int的所有可能值(较大的值无法通过float,但double)。因此,在浮点数的情况下将RHS指定给f时可能会有值更改,但在double的情况下则不会。为清楚起见:由于int/int而导致警告未返回,但由于作业float = int

为此,请参阅以下问题:what the difference between the float and integer data type when the size is same in javaStoring ints as floatsRounding to use for int -> float -> int round trip conversion

但是,使用float -Wconversion时,仍然可以用于识别受影响但可能不全面且可能不适用于此的可能行。出于-Wconversion的目的,请参阅docs/gcc/Warning-Options.html和此处gcc.gnu.org/wiki/NewWconversion

在讨论'Implicit casting Integer calculation to float in C++'

之后,可能还有兴趣

答案 4 :(得分:0)

找到这种错误的最好方法是进行非常好的单元测试。所有替代方案都不够好。

答案 5 :(得分:0)

看看这个clang-tidy detection

它捕获了这样的情况:

d = 32 * 8 / (2 + i);
d = 8 * floatFunc(1 + 7 / 2);
d = i / (1 << 4);