C 复合分配和类型转换问题
C++ compound assignment and type conversion issue
我正在计算C 中的组合(15,7)
-
我首先使用以下代码并因类型促销错误而获得错误的答案。
#include <iostream> int main() { int a = 15; double ans = 1; for(int i = 1; i <= 7; i++) ans *= (a + 1 - i) / i; std::cout << (int) ans; return 0; }
输出:
2520
-
所以我将
ans *= (a + 1 - i) / i;
更改为ans *= (double)(a + 1 - i) / i;
,但仍然得到错误的答案。#include <iostream> int main() { int a = 15; double ans = 1; for(int i = 1; i <= 7; i++) ans *= (double) (a + 1 - i) / i; std::cout << (int) ans; return 0; }
输出:
6434
-
最后,我尝试了
ans = ans * (a + 1 - i) / i
,给出了正确的答案。#include <iostream> int main() { int a = 15; double ans = 1; for(int i = 1; i <= 7; i++) ans = ans * (a + 1 - i) / i; std::cout << (int) ans; return 0; }
输出:
6435
有人可以告诉我为什么第二个不起作用?
如果未打印出ans
而不将其扔给(int)
,则会看到第二个结果是6434.9999999999990905052982270717620849609375
。这真是太近了6535
的正确答案,因此显然不再是类型的促销错误。
不,这是经典的浮点不准确。当您编写ans *= (double) (a + 1 - i) / i
时,您正在做:
ans = ans * ((double) (a + 1 - i) / i);
将此与第三版进行比较:
ans = ans * (a + 1 - i) / i;
前者首先执行划分,然后进行乘法。后者从左到右运行,因此乘法在划分之前。这种操作顺序的变化导致两者的结果略有不同。浮点计算对操作顺序非常敏感。
快速修复: truncate 结果;周围。
更好的修复:不要将浮点用于积分算术。保存划分,直到完成所有乘法后。使用long
,long long
,甚至是一个大数字库。
首先没有工作,因为您在那里有整数部门。
差异btw第二,第三个是:
ans = ans * (double(a + 1 - i) / i); // second is equal to this
vs:
ans = (ans * (a + 1 - i)) / i; // third is equal to this
因此,在乘法和除法顺序上差异。如果您将双重到整数而不是简单地掉落分数零件,您将获得相同的结果。
std::cout << int( ans + 0.5 ) << std::endl;
相关文章:
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- C++中的双指针类型转换
- 类型转换问题
- 拆分 pybind11 模块和自动类型转换问题
- 类型转换问题:返回为整数而不是浮点/类型
- 关于使用类型转换优化除法代码的问题
- C 中某些类型转换的问题
- C 复合分配和类型转换问题
- 类型转换<int>的舍入问题
- 将数据类型从C#封送至C++的类型转换问题
- 类型转换问题:字符数组的元素转换为整数变量
- 将标量乘以boost.units.quantity(自动类型转换问题?)
- 使用createprocess()时出现类型转换问题
- 垫子类型转换和访问单个像素时出现问题
- Clang 问题:构造时隐式类型转换
- 从有符号问题到无符号问题的类型转换
- C++类型转换问题
- 类型转换问题
- C++中模板类的类型转换问题