## Floating Point Rounding

### January 8, 2013

This question appears regularly at beginning-programmer discussion sites:

Write a function that takes a floating point number f and an integer n and rounds the floating point number to n places after the decimal point. For instance, given the floating point number 1000/7, rounding to 3 places would produce 142.857, rounding to 2 places would produce 142.86, rounding to 1 place would produce 142.9, and rounding to 0 places would produce 143. For extra credit, allow n to be negative, indicating rounding before the decimal point; for instance, rounding 1000/7 to -1 places would produce 140.

It’s not fair to use a built-in `round` function if your language provides one.

Your task is to write the function described above. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

Pages: 1 2

### 11 Responses to “Floating Point Rounding”

1. fisherro said

I guess I should check the suggested solution to see if it is essentially the same as mine before posting mine. ^_^

2. [...] Pages: 1 2 [...]

3. Abe C. said

> javabloggi said
>January 8, 2013 at 10:52 AM
>
>My Java solution here.

Your solution does not perform rounding correctly. You seem to be checking the digit in one more significant place value than you need to be in order to determine if rounding up is needed.

01 Enter numbers:
02 1000/7,3

However, the correct answer should be 12.857.

Here’s my java solution:

public class FPR {

public static double round(double f, int n) {
double div = Math.pow(10, (double) n);
if (div*f*10 % 10 >= 5) {
return ((double) ((int) (div*f)) + 1)/div;
} else {
return ((double) ((int) (div*f)))/div;
}
}

public static void main(String[] args) {
for (int i = 3; i >= -2; i–) {
System.out.println(“1000/7,” + i + “: ” + round(1000.0/7.0, i));
}
}
}

Thanks.

Katzby

4. Abe C. said

>However, the correct answer should be 12.857.

Sorry, I meant to say it should be 142.857.

Thanks.

Katzby

5. Joe A said

An overly complicated python version =)

```def my_round(f,n):
'''Round floating point f n places
>>> my_round(1000/7.0,3)
142.857
>>> my_round(1000/7.0,2)
142.86
>>> my_round(1000/7.0,1)
142.9
'''
num = int(f * 10**(n+1))
if num % 10 >= 5:
num+= 10
return (num/10) / 10.0**(n)

```
6. javabloggi said

>However, the correct answer should be 12.857.

>Sorry, I meant to say it should be 142.857.

>Thanks.

>Katzby

Thanks for letting me know. I corrected the mistake.

7. ardnew said

Every answer posted so far handles negative values incorrectly. Also, it doesn’t appear anyone implemented an unbiased tie-breaking scheme?

This solution handles both issues correctly (tie-breaking done with round-to-even) as well as the extra credit.

However, it doesn’t support the technical definition of significant digits.

```use strict;
use warnings;

sub round
{
my (\$f, \$n) = @_;

my \$m = 10 ** -\$n;
my \$y = \$f / \$m;

if (abs(abs(\$y) - abs(int(\$y))) - 0.5 < 1e-6)
{
return \$m *
(int(\$y) + (int(\$y) & 1) * (-1 + 2 * (\$y > 0)));
}
else
{
return int(abs(\$y) + 0.5) * (-\$m, \$m)[\$y > 0];
}
}
```
8. ardnew said

oops typo on line 11. should be:

```  if (abs(abs(\$y) - abs(int(\$y)) - 0.5) < 1e-6)
```