C++中的截断

C++中的截断,c++,floating-point,truncation,C++,Floating Point,Truncation,今天我试图编写一个程序,将用户输入的整数相加。例如,如果用户输入683,它将返回6+8+3=17 但是我在代码中遇到了一些奇怪的问题 守则: 包括 using namespace std; int computeSum(int num); int computeInteger(int num, int position); int main() { int num; int sum; int total; cin >> num; total

今天我试图编写一个程序,将用户输入的整数相加。例如,如果用户输入683,它将返回6+8+3=17

但是我在代码中遇到了一些奇怪的问题

守则: 包括

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
 }
问题


在上面的代码中,当我输入683时,对于函数computeInteger,我没有得到最后一位数字3,而是得到2作为返回值。这很奇怪,因为我认为截断只会删除浮动部分,而不会进行任何向上或向下的取整; //如果num=683,position=10,则得到68.3

这不是完全正确的,0.3不是基数2中的有理数,它将非常接近0.3,但更小,因为该数字总是向下舍入,为了缩小错误,您可以将其转换为浮点或长浮点,但这不是一种情况,因为在您的示例中,它总是0.29,如果你想了解真正发生的事情,你必须阅读计算机中的数字表示法,这里有很好的描述:

您遇到的错误是众所周知的错误,wiki页面中也有描述:

和堆栈链接:


在浮点运算中,68.3不是68.3,而是更像68.2999997。阅读。

是的,你是对的,你得到了2。让我解释一下原因: 如果num=683,我将向您展示调试器对comuteInteger函数中的值所说的内容:

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

这是清除浮点的第一步。

inline int computeInteger(int num, int position) {
    return (num / (position / 10)) % 10;
}

如果我必须做类似的事情,我将创建一个递归函数,如下所示:

int total(int num){
if(num == 0){
    return 0;
}else{
    return num%10 + total(num/10);
}
}

提取数字的常用方法是使用n%10获取最低数字的值,然后使用n/=10删除最低数字。重复此操作直到完成。

此计算不需要使用浮点。将computeSum和computeInteger替换为:


注意:您的代码允许num为负值。如果您想支持这些值,您需要添加额外的代码。

为什么输入和输出为整数时进行浮点计算?在浮点中,68.3更像68.2999997。@MM。我认为OP想要使用/而不是%operator@JonathanPotter你应该在这里加上一个答案是的,@JonathanPotter是对的。在转换为int之前,必须四舍五入到最接近的整数。添加答案+1然后,如果不想更改用于隔离数字的逻辑,只需将数字四舍五入到最接近的整数,然后再转换为int:introundsolution*10。当然,您也可以使用其他舍入函数之一。。。
int computeSum(int num)
{
    int sum = 0;
    for (; num; num /= 10)
        sum += num % 10;
    return sum;
}