2

I want to show only two decimal places from long double without rounding.

Example:

14.999999 => 14.99

12.501 => 12.50

12.505 => 12.50

There is a problem with some values.

For example this:

Excepted 204969/340 = 602.85

My result 204969/340 = 602.84

Code sample:

long long a = 204969;
long long b = 340;
long double final_result = (long double) a / (long double) b;
final_result = ((long long)(final_result * 100) / 100.00);

cout << fixed << setprecision(2) <<final_result;

Why?

Joozty
  • 460
  • 2
  • 12
  • 40
  • This is the nature of fixed-precision representations. If you expect *exact* results -- where it must be precisely 602.85 and you will not accept 602.849999999999, then don't use fixed precision representations! You should not expect a floating point operation to produce the exact result and you should not write code that cannot tolerate microscopic rounding at the last few digits. – David Schwartz Apr 18 '17 at 23:20
  • Possible duplicate of [Is floating point math broken?](http://stackoverflow.com/questions/588004/is-floating-point-math-broken) – phuclv Apr 19 '17 at 04:35

4 Answers4

3

The problem is that 204969/340, when represented as a double, is not exactly 602.85, but 602.849999999999999978, and this value times 100 gives 60284.9999999999999978, and this value converted to long long gives 60284, and this one divided by 100.00 gives 602.840000000000031832, this then rounded at a precision of 2 finally prints 602.84.

I'd do the "times 100" on base of the long and finally divide by 100.0:

long double final_result = (a*100/b)/100.00;

This then gives 602.850000000000022737, and rounded to precision 2 prints 602.85.

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
0

This is the nature of binary representations. You are asking for a result in decimal places, but floating-point doesn't have decimal places. It has binary places, and the two are incommensurable. If you want decimal places, use a decimal radix, i.e. do what it says in your title and format the double, into a char buffer, using a mask.

The technique of multiplying and then dividing by 100 does not work. See here for proof.

Community
  • 1
  • 1
user207421
  • 305,947
  • 44
  • 307
  • 483
-1

Probably a discrepancy error related to long double

I tried this code:

long long a = 204969;
long long b = 340;

double final_result = (double)(a*100/b)/100;

It gives me: 602.85.

If you need that just for typing the result, you could do it without using doubles:

 long long result = a*100/b;
 printf ("Result = %ld.%ld\n", result/100, result % 100); 
Manvir
  • 769
  • 1
  • 7
  • 15
cyanide
  • 3,885
  • 3
  • 25
  • 33
-2

Use floor function when final_result still long double so decimal places clear then cast to long long

  long long a = 204969;
  long long b = 340;
  long double final_result = (long double) a / (long double) b;
  final_result = ((long long)(floor(final_result * 100)) / 100.00);
  cout << fixed << setprecision(2) <<final_result;
amuratgencay
  • 166
  • 3