# Thread: [PHP] Round a decimal number up?

1. Aspiring Evangelist
Join Date
Aug 2003
Posts
424

## [PHP] Round a decimal number up?

Hi,

I've wasted a huge amount of time on solving something which should be relatively easy. Am I just being stupid?

I'd like to always round a decimal number up to the nearest hundreth. For example...

1.5388 = 1.54
1.5312 = 1.54
1.53 = 1.53

Ceil seems to only be for integers, and round and number_format can't always round up. I know that adding 0.005 on first is an option, you can even stick an if statement in to catch if it already just has 2 DF. This seems like a dirty way of doing things though, is there a cleaner way of doing this?

2. Retired Moderator
Join Date
Feb 2005
Location
Australia
Posts
5,842
ceil should be the answer, specifically ceil(100x)/100. (Edit. nvm - I see where you were coming from.)

3. Aspiring Evangelist
Join Date
Aug 2003
Posts
424
Originally Posted by foobic
ceil should be the answer, specifically ceil(100x)/100. (Edit. nvm - I see where you were coming from.)
Yup tried that - always rounds up to an integer. Thanks anyway, I told you it was harder than it looks

4. Retired Moderator
Join Date
Feb 2005
Location
Australia
Posts
5,842
Yes, ceil rounds up to an integer. That's why what you want ceil(100 x your number).
PHP Code:
``` <?php print centceil(1.5388) . "\n";  // 1.54 print centceil(1.5312) . "\n";  // 1.54 print centceil(1.53) . "\n";    // 1.53 function centceil(\$float) {         return ceil(\$float*100)/100; } ?> ```

5. Web Hosting Master
Join Date
Mar 2009
Posts
2,218
Originally Posted by jonathanbull
Hi,

I've wasted a huge amount of time on solving something which should be relatively easy. Am I just being stupid?

I'd like to always round a decimal number up to the nearest hundreth. For example...

1.5388 = 1.54
1.5312 = 1.54
1.53 = 1.53

Ceil seems to only be for integers, and round and number_format can't always round up. I know that adding 0.005 on first is an option, you can even stick an if statement in to catch if it already just has 2 DF. This seems like a dirty way of doing things though, is there a cleaner way of doing this?

For positive numbers:

Multiply by 100

Take the integer part.

Divide by 100.

y = floor(100*x + 0.99) / 100

Here's a test program:
Code:
```<?php
function roundup2(\$x)
{
return floor(100*\$x + 0.99) / 100;
}

echo 1.5388 , " " , roundup2(1.5388) , "\n";
echo 1.5312 , " " , roundup2(1.5312) , "\n";
echo 1.53   , " " , roundup2(1.53)   , "\n" ;

?>```
To handle negative numbers, you have to decide which way is "up".
Last edited by tim2718281; 10-09-2009 at 03:47 AM.

6. Aspiring Evangelist
Join Date
Aug 2003
Posts
424
Thank you for all your replies. Works perfectly and I've learnt an awful lot!

7. Web Hosting Master
Join Date
Mar 2009
Posts
2,218
Originally Posted by jonathanbull
Thank you for all your replies. Works perfectly and I've learnt an awful lot!
In case anyone did not realise, my suggestion gives incorrect answers for numbers such as 1.53001

There's a question of what the precision requirement is; I mistakenly assumed that four decimal digits of precision were required.

Really. the programmer should ask what precision is required, and not assume something.

8. Web Hosting Master
Join Date
Nov 2001
Location
Vancouver
Posts
2,416
Another approach - use whatever is built into PHP's type conversion mechanism:

PHP Code:
``` echo (sprintf("%01.2f", 1.53001) + 0);1.53echo gettype(sprintf("%01.2f", 1.53001) + 0);double  ```
ps: Obligatory Python example:

Code:
```>>> round(1.53001, 2)
1.53
>>> type(round(1.53001, 2))
float(x) -> floating point number
<class 'float'>```
Last edited by mwatkins; 10-12-2009 at 12:09 PM.

9. Web Hosting Master
Join Date
Mar 2009
Posts
2,218
But input of 1.53001 is suppose to deliver 1.54, not 1.53

I guess I've confused the issue with my earlier comment.

Anyway, here is a test program:

Code:
```<?php

print "1.53 Should deliver 1.53" . " : " . roundup2(1.53) . "\n";    // 1.53
print "1.531 Should deliver 1.54" . " : " . roundup2(1.531) . "\n";
print "1.5301 Should deliver 1.54" . " : " . roundup2(1.5301) . "\n";
print "1.53001 Should deliver 1.54" . " : " . roundup2(1.53001) . "\n";
print "1.53000000000000000001 Should deliver 1.54" . " : " . roundup2(1.530000000000000001) . "\n";

function roundup2(\$x) {
return ceil(\$x*100)/100;
}
?>```
If you execute it, you'll likely find that the last test case gives the wrong answer.

10. Web Hosting Master
Join Date
Nov 2001
Location
Vancouver
Posts
2,416
Originally Posted by tim2718281
But input of 1.53001 is suppose to deliver 1.54, not 1.53
Not in any math text I've ever read. You'd have to write a new, somewhat arbitrary, rounding rule to get that answer. Your inputs calculated using round(n, 2):

Code:
```def roundemup():
print "1.53 Tim says should deliver 1.53 : but does deliver %s" % round(1.53, 2)
print "1.531 Tim says should deliver 1.54 : but does deliver %s" % round(1.531, 2)
print "1.5301 Tim says should deliver 1.54 : but does deliver %s" % round(1.5301, 2)
print "1.53001 Tim says should deliver 1.54 : but does deliver %s" % round(1.53001, 2)
print "1.53000000000000000001 Tim says should deliver 1.54 : but does deliver %s" % round(1.530000000000000001, 2)

>>> roundemup()
1.53 Tim says should deliver 1.53 : but does deliver 1.53
1.531 Tim says should deliver 1.54 : but does deliver 1.53
1.5301 Tim says should deliver 1.54 : but does deliver 1.53
1.53001 Tim says should deliver 1.54 : but does deliver 1.53
1.53000000000000000001 Tim says should deliver 1.54 : but does deliver 1.53```

11. Web Hosting Master
Join Date
Mar 2009
Posts
2,218
Originally Posted by mwatkins
Not in any math text I've ever read. You'd have to write a new, somewhat arbitrary, rounding rule to get that answer. ...
Ah, you missed the stated requirement in post 1 of this thread:

"I'd like to always round a decimal number up to the nearest hundreth. For example...

1.5388 = 1.54
1.5312 = 1.54
1.53 = 1.53 "

I guess I confused the issue. Sorry about that.

12. Web Hosting Master
Join Date
Nov 2001
Location
Vancouver
Posts
2,416
Mea culpa, sorry for the distraction, thread.

You are absolutely right. I must have read that requirement and must have rejected it subconsciously as being non-sensible, to me, when the OP may have a perfectly legitimate reason for wanting same. In my own defence there are unfortunately a lot of folks who post here specifications they don't really mean, and while that isn't the case here, it seems more often than not that the community has to do some inferring and mind-reading to get to the real need. Sorry for taking things off track further folks.

I guess the least I could do is give the Python equivalent, which looks the same as Tim's function, and a test. Oh, and lets through a negative number in there... I suspect the PHP ceil approach chokes on that in the following manner:
Code:
```>>> math.ceil(-1.530001*100)/100
-1.53
>>> math.ceil(1.530001*100)/100
1.54```
A negative number-proof Python solution:
PHP Code:
``` from math import ceil, powdef founder(n, precision):    """(n:int|float, precision:int) -> float    A non standard round() function.    Always round "up" to the next <precision>th, or "down" if n is negative    i.e. founder(1.530001, 2) == 1.54; founder(-1.530001, 2) == -1.54    """    p = pow(10, precision)    return ceil(n*p)/p if n >= 0 else ceil(abs(n)*p)/(p * -1)  ```
A test:
Code:
```>>> for x in [1.54, 1.5300000001, 1.535, 1.539, 1.53123456789,
...           -1.54, -1.5300000001, -1.535, -1.539, -1.53123456789]:
...     print founder(x, 2)
...
1.54
1.54
1.54
1.54
1.54
-1.54
-1.54
-1.54
-1.54
-1.54```
Last edited by mwatkins; 10-13-2009 at 12:50 PM.

13. Retired Moderator
Join Date
Feb 2005
Location
Australia
Posts
5,842
Originally Posted by tim2718281
If you execute it, you'll likely find that the last test case gives the wrong answer.
When you try to exceed the precision of floating point maths functions you're always liable to get unexpected results. Higher precision (even arbitrary-precision) functions and libraries are available for most languages if this is an issue.

14. Junior Guru Wannabe
Join Date
Jun 2009
Location
Houston,Tx
Posts
36
I do apologize for the following, as I do not have the time to actually code this out for you, but I'd suggest doing the following:

split the string at the 100th place:

1.34000000001 becomes: 1.34 in string1 and 000000001 in string2.

if string2 > 0, add .01 to string1.
otherwise, do nothing.

Not the nicest of code ideas, but you could throw it in a function and call it whatever you want, then simply:

functionname(string)

Hope this helps.

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•