在C++中截断

car*_*995 0 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 = 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
 }
Run Code Online (Sandbox Code Playgroud)

问题

  1. 在上面的代码中,当我输入683时,对于该函数computeInteger,而不是获得最后一个数字3,我得到2作为返回值.这是非常奇怪的,因为我认为截断只会删除浮动部分而不会进行任何向上或向下舍入.当我测试代码时,cout << (int)(0.3 * 10)我确实得到3,但不是在上面的代码中.这让我感到困惑.

cer*_*wny 5

double subtract1 =(double)num/position; //如果num = 683且position = 10,这将得到68.3

这不是完全正确的,0.3不是基数2中的有理数,它将非常接近0.3但是随着数字总是向下舍入而减少,以缩小你可以将其投入浮动或长期浮动的错误但是这不是一个案例,因为在你的例子中它总是0.29,如果你想了解真正发生的事情,你必须阅读计算机中的数字表示,这里有很好的描述:

http://en.wikipedia.org/wiki/Computer_number_format

您遇到的错误是众所周知的错误,也在维基页面中描述:

http://en.wikipedia.org/wiki/Round-off_error

和堆栈链接:

什么是浮点/舍入误差的简单示例?


Jon*_*ter 5

在浮点数中,68.3不是68.3,而是更像68.299999997.阅读有关浮点舍入错误的信息.