Truncation In C++
今天,我试图编写一个程序,用以总结用户输入的整数。例如,如果用户输入
但我在代码中遇到了一些奇怪的问题
代码:包括:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | using namespace std; int computeSum(int num); int computeInteger(int num, int position); int main() { int num; int sum; int total; cin >> num; total = computeSum(num); cout << total; return 0; } int computeSum(int num) { int position = 10; int temp = num; double total = 0; bool finish = false; while(!finish) { total = total + computeInteger(num, position); if(num/ position == 0) break; position *= 10; } return total; } int computeInteger(int num, int position) { double subtract1 = (double) num / position; //if num = 683 and position = 10 , this will get 68.3 int subtract2 = num / position; //if num = 683 and position = 10 , this will get 68 double solution = subtract1 - subtract2; //take 68.3 - 68 = 0.3 return (int)(solution * 10); // return 0.3 * 10 = 3 , but instead of getting 3 this program return 0.3 * 10 = 2 } |
问题
在浮点中,68.3不是68.3,而是更像68.29999997。阅读有关浮点舍入错误的信息。
双减1=(双)数字/位置;//如果num=683,position=10,则得到68.3
这不是完全正确的,0.3不是基数2中的有理数,它非常接近于0.3,但随着数字总是向下取整,为了缩小错误范围,您可以将其强制转换为浮点或长浮点,但这不是一种情况,正如在您的示例中,它始终是0.29,如果您想了解实际发生的情况,必须阅读ab在计算机中的数字表示法中,这里很好地描述了:
http://en.wikipedia.org/wiki/computer_number_格式
您遇到的错误是众所周知的错误,也在wiki页面中描述:
http://en.wikipedia.org/wiki/round-off_错误
堆栈链接:
什么是浮点/舍入误差的简单示例?
此计算不需要使用浮点。将
1 2 3 4 5 6 7 | int computeSum(int num) { int sum = 0; for (; num; num /= 10) sum += num % 10; return sum; } |
注意:您的代码允许
要使浮点运算不受影响,请执行以下操作:
1 2 3 | inline int computeInteger(int num, int position) { return (num / (position / 10)) % 10; } |
提取数字的常用方法是使用
如果我必须做类似的事情,我将创建如下递归函数:
2是的,你是对的,你得到2。让我解释一下原因:如果num=683,我将向您展示调试器对ComuteInteger函数中的值所说的内容:
1 2 3 | double subtract1 = (double) num / position; // substract1=68.299999999999997 int subtract2 = num / position; // subtract2 = 68 return (int)(solution * 10); // 2.99999999999997 casted to int will be 2 |
这是第一步……