php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #62538 dec_ceil is wrong
Submitted: 2012-07-12 07:21 UTC Modified: 2012-07-12 08:09 UTC
From: soneta dot kumar at gmail dot com Assigned:
Status: Not a bug Package: *Math Functions
PHP Version: 5.3.14 OS: All
Private report: No CVE-ID: None
 [2012-07-12 07:21 UTC] soneta dot kumar at gmail dot com
Description:
------------
function ceil_dec($number,$precision,$separator)
{
    $numberpart=explode($separator,$number); 
$numberpart[1]=substr_replace($numberpart[1],$separator,$precision,0);
    if($numberpart[0]>=0)
    {$numberpart[1]=ceil($numberpart[1]);}
    else
    {$numberpart[1]=floor($numberpart[1]);}

    $ceil_number= array($numberpart[0],$numberpart[1]);
    return implode($separator,$ceil_number);
}

echo ceil_dec(1.019,2,"."); 
// Actual output = 1.2
// Expected output =  1.02


Test script:
---------------
This is solution :
function ceil_dec($number,$precision,$separator='.')
{
    $appendZero = false;
    $numberpart=explode($separator,$number); 
    $numberpart[1]=substr_replace($numberpart[1],$separator,$precision,0); 
    if($numberpart[1][0] == 0)	{ $appendZero = true;}
    if($numberpart[0]>=0)
    {$numberpart[1]=ceil($numberpart[1]);}
    else
    {$numberpart[1]=floor($numberpart[1]);}
    if($appendZero){ $numberpart[1] = (int) '0'.$numberpart[1];}	
    $ceil_number= array($numberpart[0],$numberpart[1]);
    return implode($separator,$ceil_number);
}

Expected result:
----------------
// Expected output =  1.02

Actual result:
--------------
// Expected output =  1.2

Patches

correct-ceil-dec-function (last revision 2012-07-12 07:25 UTC by soneta dot kumar at gmail dot com)

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-07-12 08:09 UTC] rasmus@php.net
-Status: Open +Status: Not a bug
 [2012-07-12 08:09 UTC] rasmus@php.net
So what is the bug in PHP? I see the bug in your code, but I don't see a PHP bug 
here.

Step-by-step, exploding 1.019 on '.':

$numberpart=explode($separator,$number);

gives you: [0] => 1  [1] => 019

Now we take 019 and insert the separator '.' and position precision (2):

$numberpart[1]=substr_replace($numberpart[1],$separator,$precision,0);

Now we have: [0] => 1   [1] => 01.9

And since $numberpart[0]>0 we do the ceil line:

$numberpart[1]=ceil($numberpart[1]);

ceil(01.9) is obviously going to be 2 which is where you went wrong. Since 
ceil() takes a float it is going to convert the string 01.9 to 1.9.

so we now have:  [0] => 1   [1] => 2

This line seems redundant:

$ceil_number= array($numberpart[0],$numberpart[1]);

You are taking array elements and putting them into an array. Why not just use 
the original array, but regardless, you $ceil_number array will have 1,2 in it.

return implode($separator,$ceil_number);

and this implode will return "1.2" as it should.

Why are you not just using number_format() here?

number_format(1.019,2) gives you what you want and it optionally takes decimal 
and thousands separators too.
 [2012-07-12 09:18 UTC] anon at anon dot anon
@Rasmus: The bug report appears to be about a function in a user comment on the ceil manual page: http://php.net/manual/en/function.ceil.php
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 06:01:30 2024 UTC