是否有g ++警告或其他工具可以识别整数除法(截断为零)?我有成千上万行代码进行计算,不可避免地会出现数值错误,这通常是由于需要定位的“float = int / int”。我需要一种合理的方法来找到它们。
答案 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)
-Wconversion
的gcc:将浮点变量的类型从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 java,Storing ints as floats和Rounding to use for int -> float -> int round trip conversion
但是,使用float
-Wconversion
时,仍然可以用于识别受影响但可能不全面且可能不适用于此的可能行。出于-Wconversion
的目的,请参阅docs/gcc/Warning-Options.html和此处gcc.gnu.org/wiki/NewWconversion
答案 4 :(得分:0)
找到这种错误的最好方法是进行非常好的单元测试。所有替代方案都不够好。
答案 5 :(得分:0)
看看这个clang-tidy detection。
它捕获了这样的情况:
d = 32 * 8 / (2 + i);
d = 8 * floatFunc(1 + 7 / 2);
d = i / (1 << 4);