Truncation In C++

3.5k Views Asked by At

Today I was trying to write a program that would sum up the integer input by user. For example if user input 683 it would return 6 + 8 + 3 = 17.

But I encounter some weird problem in my code

The Code :

#include

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
 }

The Question

  1. In the above code, when I input 683, for the function computeInteger, instead of getting the last digit 3 I get 2 as a return value. This is very weird as I thought truncation would only remove the floating part and not doing any round up or down.When I test the code cout << (int)(0.3 * 10) I did get 3 , but not in the code above. It makes me confuse.
7

There are 7 best solutions below

0
On

If I'll have to do something similar I'll create a recursive function like below:

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

double subtract1 = (double) num / position; //if num = 683 and position = 10 , this will get 68.3

This is not entirely true, the 0.3 is not the rational number in base 2, those it will be very close to the 0.3 but less as the number is always rounded down, to narrow the mistake you can cast it to float or long float but this is not a case, as in your example it will always be 0.29, if you want to understand what really happens you must read about the number representation in the computers, it is very well described here:

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

The error you encountered is well known mistake also described in the wiki page:

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

And Stack link:

What is a simple example of floating point/rounding error?

1
On

In floating point, 68.3 isn't 68.3, but is more like 68.299999997. Read about floating point rounding errors.

0
On

Yes, you're right you get 2. Let me explain why: if the num = 683 I'll show you what the debugger says for the values from your comuteInteger function:

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

This is for the first step..

0
On

To get floating point out of the way:

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

There is no need to use floating-point for this calculation. Replace computeSum and and computeInteger with:

int computeSum(int num)
{
    int sum = 0;
    for (; num; num /= 10)
        sum += num % 10;
    return sum;
}

Note: Your code permits negative values for num. If you want to support those, you will need to add additional code.

0
On

The usual approach for picking off digits is to use n % 10 to get the value of the lowest digit then n /= 10 to remove the lowest digit. Repeat until done.