c++ - 大 double 除以大 int

标签 c++ double numerical

我正在编写物理模拟代码,最近遇到了异常结果。我设法调试我的程序,错误在于大 double 除以大整数,其形式如下:

cout << my_large_double/my_large_int << endl

my_large_double 的阶数为 -10^{9} ,而我的两个整数的乘积的阶数为 10^{9} ,则返回阶数为 1 的正值。 我通过将分母强制转换为双倍来修复此问题:

cout << my_large_double/( (double)my_large_int1*my_large_int2) << endl

但我想了解错误是从哪里来的,有什么方法可以防止它们通常发生?

更新:我跳过了第一个问题中重要的细节:int 实际上是两个 int 的乘积。

最佳答案

这取决于表达式的具体编写方式。

如果你这样写:

my_large_double / my_large_int1 / my_large_int2

那么它相当于:

(my_large_double / my_large_int1) / my_large_int2

这应该会给你相当准确的结果; my_large_int1 在第一次除法之前提升为 doublemy_large_int2 在第二次除法之前提升为 double

如果你这样写:

my_large_double / (my_large_int1 * my_large_int2)

然后乘法以两个整数变量的类型完成,并且根据它们的值,您可能会出现溢出(这可以给您一个比数学乘积小得多的值 - 尽管严格来说有符号整数的行为溢出未定义)。

要记住的重要一点是,在大多数情况下,每个 C 表达式都是单独有效计算的;它的类型不受它出现的上下文的影响。表达式 my_large_int1 * my_large_int2 是整数乘法,即使结果是浮点除法的操作数或分配给浮点变量。

任何操作数均为整数的运算都是整数运算。如果一个操作数为 double,另一个为 int,则 int 操作数将提升为 double

即使是这样:

double temp = my_large_int1 * my_large_int2;
... my_large_double / temp ...

将在使用结果初始化 temp 之前执行整数乘法,如下:

my_large_double / (double)(my_large_int1 * my_large_int2)

有同样的问题。

正如您所发现的,解决方案是将一个或两个整数操作数转换为 double:

my_large_double / ((double)my_large_int1 * (double)my_large_int2)

(为了对称和清晰,您也可以同时转换它们。)

关于c++ - 大 double 除以大 int,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20222737/

相关文章:

floating-point - 二进制 float 的十进制精度

零附近的 C++ 浮点比较与 Gtest 失败

c++ - 重载operator=时出现: expected constructor, destructor, or type conversion before '&' token错误

c++ - cppcheck: header 中的函数定义

java - 换算成小数点后2位

c++ - 二进制表达式 ('double(*)(double' 和 'double' 的无效操作数)

c++ - 按名称存储和引用变量列表

c++ - 映射继承

c# - 如何在 C# 中计算非常大的 double 组的轮数

c++ - 小数点错误