定位因整数除法导致的数值错误

发布于 2024-11-08 22:22:49 字数 113 浏览 0 评论 0原文

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

Is there a g++ warning or other tool that can identify integer division (truncation toward zero)? I have thousands of lines of code with calculations that inevitably will have numerical errors typically due to "float = int/int" that need to be located. I need a reasonable method for finding these.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

偏爱自由 2024-11-15 22:22:49

尝试-Wconversion

来自 gcc 的手册页:

警告可能的隐式转换
改变一个值。这包括
实数和整数之间的转换,
当“x”为“double”时,如“abs (x)”;
有符号和之间的转换
无符号,如“无符号 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:警告:从“int”转换为“float”可能会改变其值

#include <iostream>

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

    std::cout << f;

    return 0;
}

Try -Wconversion.

From gcc's man page:

Warn for implicit conversions that may
alter a value. This includes
conversions between real and integer,
like "abs (x)" when "x" is "double";
conversions between signed and
unsigned, like "unsigned ui = -1"; and
conversions to smaller types, like
"sqrtf (M_PI)". Do not warn for
explicit casts like "abs ((int) x)"
and "ui = (unsigned) -1", or if the
value is not changed by the conversion
like in "abs (2.0)". Warnings about
conversions between signed and
unsigned integers can be disabled by
using -Wno-sign-conversion.

For C++, also warn for conversions
between "NULL" and non-pointer types;
confusing overload resolution for
user-defined conversions; and
conversions that will never use a type
conversion operator: conversions to
"void", the same type, a base class or
a reference to them. Warnings about
conversions between signed and
unsigned integers are disabled by
default in C++ unless
-Wsign-conversion is explicitly enabled.

For the following sample program (test.cpp), I get the error 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;
}
信仰 2024-11-15 22:22:49

我很难指出这些数字错误。您要求进行整数计算,并获得了整数计算的正确数字。如果这些数字不可接受,则要求进行浮点计算:

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;

I have a hard time calling these numerical errors. You asked for integer calculations, and got the correct numbers for integer calculations. If those numbers aren't acceptable, then ask for floating point calculations:

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;
孤星 2024-11-15 22:22:49

关于-Wconversion<的评论gcc 的 /a>:

更改浮点变量的类型floatdouble 使警告消失:

$ 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 捕获)。因此,在 float 情况下将 RHS 分配给 f 时,值可能会发生变化,但在 double 情况下则不会。明确一下:返回警告不是因为 int/int,而是因为赋值 float = int

为此,请参阅以下问题:java中当大小相同时float和integer数据类型有什么区别, 将整数存储为浮点数用于 int 的舍入 ->浮动-> int 往返转换

但是,当使用 float 时,-Wconversion 仍可用于识别可能受影响的行,但并不全面,实际上并不适用于那。对于 -Wconversion 的目的,请参阅 docs/gcc/Warning-Options.html 和此处 gcc.gnu.org/wiki/NewWconversion

可能感兴趣的还有以下讨论'在 C++ 中隐式转换整数计算以进行浮点数'

Remark on -Wconversion of gcc:

Changing the type of the floating point variable from float to double makes the warning vanish:

$ cat 'file.cpp'

#include <iostream>

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

   std::cout << f;
}

Compiling with $ g++-4.7 -Wconversion 'file.cpp' returns no warnings (as $ clang++ -Weverything 'file.cpp').

Explanation:

The warning when using the type float is not returned because of the totally valid integer arithmetics, but because float cannot store all possible values of int (larger ones cannot be captured by float but by double). So there might be a change of value when assigning RHS to f in the case of float but not in the case of double. To make it clear: The warning is not returned because of int/int but because of the assignment float = int.

For this see following questions: what the difference between the float and integer data type when the size is same in java, Storing ints as floats and Rounding to use for int -> float -> int round trip conversion

However, when using float -Wconversion could still be useful to identify possible lines which are affected but is not comprehensive and is actually not intended for that. For the purpose of -Wconversion see docs/gcc/Warning-Options.html and here gcc.gnu.org/wiki/NewWconversion

Possibly of interest is also following discussion 'Implicit casting Integer calculation to float in C++'

羞稚 2024-11-15 22:22:49

发现此类错误的最佳方法是进行真正良好的单元测试。所有替代方案都不够好。

The best way to find such error is to have really good unit tests. All alternatives are not good enough.

终止放荡 2024-11-15 22:22:49

看看这个 clang-tidy 检测

它捕获这样的情况:

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

Have a look at this clang-tidy detection.

It catches cases like this:

d = 32 * 8 / (2 + i);
d = 8 * floatFunc(1 + 7 / 2);
d = i / (1 << 4);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文