-2

I need to calculate the difference value between 2 string numbers by only taking only the first precision. I have to convert to double first then calculate the difference as below

#include <iostream>
#include <math.h>
#include <string>

using namespace std;

int main()
{
    string v1 = "1568678435.244555";
    string v2 = "1568678435.300111";

    double s1 = atof(v1.substr(0,12).c_str());  // take upto first precision and convert to double
    double s2 = atof(v2.substr(0,12).c_str());  // take upto first precision and convert to double
    std::cout<<s1<<" "<<s2<<" "<<s2-s1<<endl;
    if (s2-s1 >= 0.1)
        cout<<"bigger";
    else
        cout<<"smaller";

    return 0;
}

I expect the calculation would be 1568678435.3 - 1568678435.2 = 0.1 . But this program returns this value :

1.56868e+09 1.56868e+09 0.0999999                                                                               
smaller

Why is that and how to get the value that I want properly?

gameon67
  • 3,981
  • 5
  • 35
  • 61
  • 3
    It sounds like this exercise is designed to teach you about precision limits in computing. – paddy May 14 '20 at 01:13
  • 2
    I suggest you search SO for the words floating, point, precision, limit, and inaccuracy, and read one of the bazillion answers on the matter :-) – paxdiablo May 14 '20 at 01:16

2 Answers2

4

Floating point format has limited precision. Not all values are representable. For example, the number 1568678435.2 is not representable (in IEEE-754 binary64 format). The closest representable value is:

1568678435.2000000476837158203125

1568678435.3 is also not a representable value. The closest reprecentable value is:

1568678435.2999999523162841796875

Given that the floating point values that you start with are not precise, it should be hardly surprising that the result of the calculation is also not precise. The floating point result of subtracting these numbers is:

0.099999904632568359375

Which very close to 0.1, but not quite. The error of the calculation was:

0.000000095367431640625

Also note that 0.1 is itself not a representable number, so there is no way to get that as the result of a floating point operation no matter what your inputs are.


how to get the value that I want properly?

To print the value 0.1, simply round the output to a sufficiently coarse precision:

std::cout << std::fixed << std::setprecision(1) << s2-s1;

This works as long as the error of the calculation doesn't exceed half of the desired precision.

If you don't want to deal with any accuracy error in your calculation, then you mustn't use floating point numbers.

eerorika
  • 232,697
  • 12
  • 197
  • 326
0

You should round the difference between the values.

if (round((s2-s1) * 10) >= 1)
    cout<<"bigger";
else
    cout<<"smaller";