4

I am porting some code from Matlab to C++.

In Matlab

format long
D = 0.689655172413793 (this is 1.0 / 1.45)
E = 2600 / D
// I get E = 3.770000000000e+03

In C++

double D = 0.68965517241379315; //(this is 1.0 / 1.45)
double E = 2600 / D;
//I get E = 3769.9999999999995

It is a problem for me because in both cases I have to do rounding down to 0 (Matlab's fix), and in the first case (Matlab) is becomes 3770, whereas in the second case (C++) it becomes 3769.

I realise that it is because of the two additional least significant digits "15" in the C++ case. Given that Matlab seems to only store up to 15 significant digits of precision in double precision (as shown above - 0.689655172413793), how can I effectively tell C++ to ignore the "15" at the back?

All calculations are done in double precision.

Daniel
  • 36,610
  • 3
  • 36
  • 69
lppier
  • 1,927
  • 3
  • 24
  • 62
  • 2
    Where does the value of `D` come from? Why don't you just multiply `2600*1.45`? – Simon Kraemer Feb 25 '16 at 10:28
  • floats and their representations are always a problem; you're calculating 20/29 ... that's not fitting any of precesitions, either in base2 nor in base10 – Tommylee2k Feb 25 '16 at 10:32
  • take a look here: https://en.wikipedia.org/wiki/Round-off_error#Representation_error perhaps a library implementing fractions could help you – Tommylee2k Feb 25 '16 at 10:43
  • Ok, so three words, just don't. In case precision to the 17th decimal is required, you should definitely handle this more sophisticated. Find out why you need to do it the way you do and rewrite it in a safe way. Apart from this, Matlab and c++ follows the same standard. See answers below. – patrik Feb 25 '16 at 12:28

2 Answers2

16

You got confused by the different ways C++ and MATLAB are printing double values. MATLAB's format long only prints 15 significant digits while C++ prints 17 significant digits. Internally both use the same numbers: IEEE 754 64 bit floating point numbers. To reproduce the C++-behaviour in MATLAB, I defined a anonymous function disp17 which prints numbers with 17 significant digits:

>> disp17=@(x)(disp(num2str(x,17)))

disp17 = 

    @(x)(disp(num2str(x,17)))

>> 1.0 / 1.45

ans =

   0.689655172413793

>> disp17(1.0 / 1.45)
0.68965517241379315

You see the result in MATLAB and C++ is the same, they just print a different number of digits. If you now continue in both programming languages with the same constant, you get the same result.

>> D = 0.68965517241379315 %17 digits, enough to represent a double.

D =

   0.689655172413793

>> ans = 2600 / D %Result looks wrong

ans =

     3.770000000000000e+03

>> disp17(2600 / D) %But displaying 17 digits it is the same.
3769.9999999999995

The background for printing 17 or 15 digits:

Community
  • 1
  • 1
Daniel
  • 36,610
  • 3
  • 36
  • 69
-3

If I understand what you are trying to achieve, using ceil function might help:

ans = ceil(ans); /* smallest integral value that is not less than ans. */
// now ans in C++ is also be 3970.

Here is usage reference.

vcp
  • 962
  • 7
  • 15