girish
girish

Reputation: 305

PHP Ceil and Floor to the nearest 100 with rounding

I have 2 different functions ceiling and flooring which will ceil or floor the given number to the number specified in the function. Functions are as below:

function ceiling($number, $significance) {
if ($significance != null) {
    return (is_numeric($number) && is_numeric($significance) ) ? (ceil($number / $significance) * $significance) : $number;
} else {
    return $number;
}}

function flooring($number, $significance) {
if ($significance != null) {
    return (is_numeric($number) && is_numeric($significance) ) ? (floor($number / $significance) * $significance) : $number;
} else {
    return $number;
}}

With the above functions, the results will be as follows:

echo ceiling(125, 100);     // 200
echo ceiling(2785, 1000);   // 3000

echo flooring(125, 100);    // 100
echo flooring(2785, 1000);  // 2000

Problem Statement:

I have a particular number say, 1234 which will be multiplied by the exchange rate which is say 0.7268. This will generate a particular number but it has to be always rounded to the nearest 100 using the ceiling function with significance as 100.

$rate = 0.7268;
$res = $rate * 1234;
$res = ceiling($res, 100); // result : 900

The result of the above will be 900 after rounding it to the nearest 100.

Now in a different part of the code, I have access to the result 900, exchange rate 0.7268 and the value used for rounding which is 100 in our case. Will it be possible to get the initial value 1234 as the answer.

I am guessing this has to use the flooring function somehow but I couldn't quiet make it work.

This is what i have tried:

$final = $res * (1 / $rate);
$final = flooring($final, 100); // result : 1200 which is wrong.

The right answer to this is 1234.

Thanks.

Upvotes: 1

Views: 3653

Answers (2)

syck
syck

Reputation: 3039

First, your flooring() function does not do the opposite of the ceiling() function, as for example serialize() and unserialize() do. It does the same thing in the opposite direction.

But even if you had an unceiling() function, it would have no means to determine which value between x00 and x99 it should return.

Conclusion: This cannot possibly work.

Upvotes: 2

Djave
Djave

Reputation: 9359

From my comment: I don't think it will be as far as I can tell. When you round something, by its very nature you are removing precision from it. That means that as you reverse the process you won't be able to get the accuracy 'back'.

Alternative

If you have a class that you are using for the money, then you could easily have a function. Off the top of my head:

class Money{
    public $amount;

    function ceiled(){
        return ceiling($this->amount, 100); 
    }
}

This means that in your code, you could still do things like multiply the $amount wherever you need to, but whenever you need to display to the user a 'ceiled' version of the number, you just ask for it as a one off i.e.

<?php 
$money = new Money();
$money->amount = 1234;
echo "Current amount is roughly " . $money->ceiled();

// apply exchange rate 
$money->amount *= 0.7268;
echo "New amount is roughly " . $money->ceiled();

So you never save the ceiled amount as the variable, you just display it to the user while a more accurate variable exists in your code.

Upvotes: 1

Related Questions