将大的double除以大的int
Dividing large double by large int
我正在编写一个物理模拟,最近遇到了异常结果。我设法调试了我的程序,错误是一个大的double除以一个大int,形式如下:
cout << my_large_double/my_large_int << endl
对于-10^{9}阶的my_large_double和10^{9}阶的两个int的乘积,返回的是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)
(为了对称和清晰起见,您还可以同时铸造它们。)
IEEE格式的double
最多可容纳53位的int
,而int
通常为31位。您的解决方案很好,可以提前转换为double
,这样您就不会在乘法中遇到整数溢出。
- C++在数学计算中将double转换为int
- 使输出流式处理运算符适用于 boost::variant<std::vector<int>、int、double 的正确方法是什么>
- 进程为包含double但不包含int的模板返回了-103741819(0xC0000005)
- 在C++中,为什么int可以使用new运算符初始化变量,而double不能
- 错误:"int pow(double,int)"与上一个声明int pov(double a,int
- 重载函数 int vs double
- 如何修复 E2015 "ambiguity between pow(double,double) and pow(float,int)"
- 未定义模板'std::__1::function<int (double, double, double, double)>'的隐式实例化
- C++ - extern int (double)
- 在向量中存储模板化对象(在<int><double>单个向量中存储类、类)
- 有没有办法<int><double>在使用 C++11 函数调用期间自动将"向量"提升为"向量"?
- 获取系统时间(以毫秒为单位)作为int/double
- 如何使用非法名称(例如 "int double = 0")声明变量?
- 从文件中读取数据类型string, int double.将每一行数据放入对象向量中
- c-string和(int,double,float)之间的动态分配
- 英特尔C++错误:"pair"不是非静态数据成员或类"std::pair<const int, double>"的基类
- C/ c++: do内置对象,如' int ' ' double '在程序运行期间始终保持在内存中的确切位置
- 一个如何实现string和long, int, double模板函数的建议
- 对于最简单的类型,我应该使用boost::optional来表示可以为null的int double等吗
- 映射和节点,错误智能感知:不存在从"const std::pair<const int, double>"到"Node"的合适用户定义转换