13

I have a part in my code where I need to divide and have a remainder instead of a decimal answer.

How can I do this?

Pang
  • 9,564
  • 146
  • 81
  • 122

9 Answers9

24
$quotient = intval($dividend / $divisor);
$remainder = $dividend % $divisor;

Using intval instead of floor will round the quotient towards zero, providing accurate results when the dividend is negative.

Alex Barrett
  • 16,175
  • 3
  • 52
  • 51
17

You can do what you are describing using the "%" (modulus) operator. The following code is an example of dividing with a remainder.

$remainder=$num % $divideby;
$number=explode('.',($num / $divideby));
$answer=$number[0];
echo $answer.' remainder '.$remainder;
Sam Becker
  • 19,231
  • 14
  • 60
  • 80
5

A solution for positive and negative numbers:

$quotient = $dividend / $divison;
$integer = (int) ($quotient < 0 ? ceil($quotient) : floor($quotient));
$remainder = $dividend % $divisor;
Gumbo
  • 643,351
  • 109
  • 780
  • 844
4

The mathematical correct answer is:

remainder = dividend % divisor;
quotient = (dividend - remainder) / divisor;

and the remainder verifies the condition 0 <= remainder < abs(divisor).

Unfortunately, many programming languages (including PHP) don't handle the negative numbers correctly from the mathematical point of view. They use different rules to compute the value and the sign of the remainder. The code above does not produce the correct results in PHP.

If you need to work with negative numbers and get the mathematical correct results using PHP then you can use the following formulae:

$remainder = (($dividend % $divider) + abs($divider)) % abs($divider);
$quotient = ($dividend - $remainder) / $divider;

They rely on the way PHP computes modulus with negative operands and they may not provide the correct result if they are ported to a different language.

Here is a script that implements these formulae and checks the results against the values provided as example in the aforementioned mathematical correct answer.

axiac
  • 68,258
  • 9
  • 99
  • 134
  • To clarify, the first "code" snippet is a *mathematical* expression. `%` is the [mathematical modulo operator](https://en.wikipedia.org/wiki/Modulo_operation). There, see *"In mathematics, the result of the modulo operation is an equivalence class, and any member of the class may be chosen as representative; however, the usual representative is the **least positive residue**, the smallest nonnegative integer which belongs to that class, i.e. the remainder of the Euclidean division."* Axiac is observing that PHP, for negative values, does not return *least positive residue*. – ToolmakerSteve Aug 07 '19 at 16:32
1

If you need to look it up, the % operator is called mod (or modulus).

Adam Hopkinson
  • 28,281
  • 7
  • 65
  • 99
0

Use This Function Its an array Description array gmp_div_qr ( resource $n , resource $d [, int $round ] )

The function divides n by d .

reference : http://php.net/manual/en/function.gmp-div-qr.php

V A S
  • 3,338
  • 4
  • 33
  • 39
0

I had to develop this approach because my numerator was a float value and modulus was rounding results.

Using Raffaello's approach offered here for dividing floats and taking from Sam152's solution above came up with the following.

$a = 2.1;
$b = 8;
$fraction = $a / (float) $b;
$parts = explode('.', $fraction);                
$int = $parts[0];
$remainder = $score - ($int*$b) ;  
Community
  • 1
  • 1
luckyape
  • 722
  • 8
  • 22
0

An example to show strings like 1 hour 6 minutes using floor() and modulus (%) if only minutes/seconds given:

$minutes=126;

if($minutes < 60) {
    $span= $minutes.' min.';
} else {
    $rem=$minutes % 60;
    $span=floor($minutes/60).' h. '. (($rem>0) ? $rem.' min.':'');
}

// echo 'Hello Jon Doe, we notify you that even will last for 2 h. 6 min.
echo 'Hello Jon Doe, we notify you that event will last for '.$span;
K.Alex
  • 91
  • 3
0

It seems to be an old post, but for those who might be interested here is a very light package that could meet your needs: https://github.com/romainnorberg/residue (feedbacks are welcome)

Romain Norberg
  • 947
  • 6
  • 6