我正在编写物理模拟代码,最近遇到了异常结果。我设法调试我的程序,错误在于大 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
在第一次除法之前提升为 double
,my_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/