How to divide numbers without remainder in PHP? - php

How does one divide numbers but exclude the remainder in PHP?

Just cast the resulting value to an int.
$n = (int) ($i / $m);
Interesting functions (depending on what you want to achieve and if you expect negative integers to get devided) are floor(), ceil() and round().

PHP 7 has a new built-in function for this named intdiv.
Example:
$result = intdiv(13, 2);
The value of $result in this example will be 6.
You can find the full documentation for this function in the PHP documentation.

For most practical purposes, the accepted answer is correct.
However, for builds where integers are 64 bits wide, not all possible integer values are representable as a double-precision float; See my comment on the accepted answer for details.
A variation of
$n = ($i - $i % $m) / $m;
(code taken from KingCrunch's comment under another answer) will avoid this problem depending on the desired rounding behavior (bear in mind that the result of the modulus operator may be negative).

In addition to decisions above like $result = intval($a / $b) there is one particular case:
If you need an integer division (without remainder) by some power of two ($b is 2 ^ N) you can use bitwise right shift operation:
$result = $a >> $N;
where $N is number from 1 to 32 on 32-bit operating system or 64 for 64-bit ones.
Sometimes it's useful because it's fastest decision for case of $b is some power of two.
And there's a backward (be careful due to overflow!) operation for multiplying by power of two:
$result = $a << $N;
Hope this helps for someone too.

or you could just do intval(13 / 2)
gives 6

use modulo in php:
$n = $i % $m;

Related

Why does 2e3 return 2000? Isn't 2 to the 3rd power equal to 8?

This code:
$g = 2e3;
echo $g;
echo <br>;
echo "var_dump g gives:<br>";
Displays:
2000
float(2000)
I don't understand why it wouldn't display "8" and "float(8)"? Isn't 2 to the 3rd power equal to 8 ??
I tried looking for this question on this website already. Any help would be greatly appreciated. I did figure out that for 2e2 it displays 200. So it sounds like it just adds that many zeros to the end of the number instead of finding the 3rd power of 2. When I search for how to write exponential in php, the answers I've found said to use 'e' or 'E', but that doesn't seem to work or I've forgotten basic math. I'm sure somebody on here has a very simple answer for me.
Ok so why does $g = 2^3; give me 1? How can I write 2 to the 3rd power in php?
It's called scientific notation (or in this case "E notation").
2e3 is the same as 2 x 10^3, which is 2000.
If you want 2^3, you can use
$g = pow(2, 3);
Or in PHP 5.6+:
$g = 2**3;
Note: You need to use pow() (or **) because in PHP, when you do $g = 2^3;, you are doing 2 XOR 3.
When you read something like xey that is called scientific notation. It represents x times 10 to the power of y, or essentilly, add y zeroes to x (for positive values of y). So in this case, it's 2 * 10^3 = 2,000
2e3 is scientific notation for 2000.0. It is the same as 2.0e03. Use the pow() function:
echo pow(2, 3); // 8

PHP ceil gives wrong results if input is a float with no decimal

I've been wrestling with PHP's ceil() function giving me slightly wrong results - consider the following:
$num = 2.7*3; //float(8.1)
$num*=10; //float(81)
$num = ceil($num); //82, but shouldn't this be 81??
$num/=10; //float(8.2)
I have a number which may have any number of decimal places, and I need it rounded up to one decimal place.
i.e 8.1 should be 8.1, 8.154 should be 8.2, and 8 should be left as 8.
How I've been getting there is to take the number, multiply by 10, ceil() it, then divide by ten but as you can see I'm getting an extra .1 added in some circumstances.
Can anyone tell my why this is happening, and how to fix it?
Any help greatly appreciated
EDIT: had +=10 instead of *=10 :S
EDIT 2:
I didn't explicitly mention this but I need the decimal to ALWAYS round UP, never down - this answer is closest so far:
rtrim(rtrim(sprintf('%.1f', $num), '0'), '.');
However rounds 3.84 down to 3.8 when I need 3.9.
Sorry this wasn't clearer :(
Final Edit:
What I ended up doing was this:
$num = 2.7*3; //float(8.1)
$num*=10; //float(81)
$num = ceil(round($num, 2)); //81 :)
$num/=10; //float(8.1)
Which works :)
This is more than likely due to floating point error.
http://support.microsoft.com/kb/42980
http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html
http://joshblog.net/2007/01/30/flash-floating-point-number-errors/
http://en.wikipedia.org/wiki/Floating_point
You may have luck trying this procedure instead.
<?php
$num = 2.7*3;
echo rtrim(rtrim(sprintf('%.1f', $num), '0'), '.');
Floats can be a fickle thing. Not all real numbers can be properly represented in a finite number of binary bits.
As it turns out, a decimal section of 0.7 is one of those numbers (comes out 0.10 with an infinity repeating "1100" after it). You end up with a number that's ever so slightly above 0.7, so when you multiply by 10, you have a one's digit slightly above 7.
What you can do is make a sanity check. Take you float digit and subtract it's integer form. If the resulting value is less than, say, 0.0001, consider it to be an internal rounding error and leave it as-is. If the result is greater than 0.0001, apply ceil() normally.
Edit: A fun example you can do if you're on windows to show this is to open up the built in calculator application. Put in "4" then apply a square root function (with x^y where y=0.5). You'll see it properly displays "2". Now, subtract 2 from it and you'll see that you don't have 0 as a result. This is caused by internal rounding errors when it attempted to compute the square root of 4. When displaying the number 2 earlier, it knew that those very distant trailing digits were probably a rounding error, but when those are all that's left, it gets a bit confused.
(Before anybody gets onto me about this, I understand that this is oversimplified, but nonetheless I consider it a decent example.)
Convert your number to a string and ceil the string.
function roundUp($number, $decimalPlaces){
$multi = pow(10, $decimalPlaces);
$nrAsStr = ($number * $multi) . "";
return ceil($nrAsStr) / $multi;
}
The problem is that floating point numbers are RARELY what you expect them to be. Your 2.7*3 is probably coming out to be something like 81.0000000000000000001, which ceil()'s up to 82. For this sort of thing, you'll have to wrap your ceil/round/floor calls with some precision checks, to handle those extra microscopic differences.
Use %f instead of %.1f.
echo rtrim(rtrim(sprintf('%f', $num), '0'), '.');
Why not try this:
$num = 2.7*3;
$num *= 100;
$num = floor($num);
$num /= 10;
$num = ceil($num);
$num /= 10;

Weird modulo result

I observed the following and would be thankful for an explanation.
$amount = 4.56;
echo ($amount * 100) % 5;
outputs : 0
However,
$amount = 456;
echo $amount % 5;
outputs : 1
I tried this code on two separate PHP installations, with the same result. Thanks for your help!
I strongly suspect this is because 4.56 can't be exactly represented as a binary floating point number, so a value very close to it is used instead. When multiplied by 100, that comes to 455.999(something), and then the modulo operator truncates down to 455 before performing the operation.
I don't know the exact details of PHP floating point numbers, but the closest IEEE-754 double to 4.56 is 4.55999999999999960920149533194489777088165283203125.
So here's something to try:
$amount = 455.999999999;
echo $amount % 5;
I strongly suspect that will print 0 too. From some PHP arithmetic documentation:
Operands of modulus are converted to integers (by stripping the decimal part) before processing.
Use fmod to avoid this problem.

How is -13 % 64 = -13 in PHP?

Derived from this question : (Java) How does java do modulus calculations with negative numbers?
Anywhere to force PHP to return positive 51?
update
Looking for a configuration setting to fix, instead hard-guessing
Or other math function like bcmath?
updated
Not entire convinced by that java answer, as it does not take account of negative modulus
-13+(-64) =?
Anyway, the post you referenced already gave the correct answer:
$r = $x % $n;
if ($r < 0)
{
$r += abs($n);
}
Where $x = -13 and $n = 64.
If GMP is available, you can use gmp_mod
Calculates n modulo d. The result is always non-negative, the sign of d is ignored.
Example:
echo gmp_strval(gmp_mod('-13', '64')); // 51
Note that n and d have to be GMP number resources or numeric strings. Anything else won't work¹
echo gmp_strval(gmp_mod(-13, 64));
echo gmp_mod(-13, 64);
will both return -51 instead (which is a bug).
¹ running the above in this codepad, will produce 51 in all three cases. It won't do that on my development machine.
The modulo operation should find the remainder of division of a number by another. But strictly speaking in most mainstream programming languages the modulo operation malfunctions if dividend or/and divisor are negative. This includes PHP, Perl, Python, Java, C, C++, etc.
Why I say malfunction? Because according to mathematic definition, a remainder must be zero or positive.
The simple solution is to handle the case yourself:
if r < 0 then r = r + |divisor|;
|divisor| is the absolute value of divisor.
Another solution is to use a library (as #Gordon pointed). However I wouldn't use a library to handle a simple case like this.
I hate using if in this case when you can calculate it right away.
$r = ($x % $n + $n) % $n;
when $n is positive.
The PHP manual says that
The result of the modulus operator % has the same sign as the dividend — that is, the result of $a % $b will have the same sign as $a. For example
so this is not configurable. Use the options suggested in the question you linked to

Get remainder only from a division using PHP

I am dividing 19/5 where by I have used 19/5 but I am unable to get the remainder only.
How do I get it.
Thanks
Jean
echo 19 % 5;
should return 4, which is the remainder of 19/5 (3 rem 4)
There is no need to use floor, because the result of a modulus operation will always be an integer value.
If you want the remainder when working with floating point values, then PHP also has the fmod() function:
echo fmod(19,5.5);
EDIT
If you want the remainder as a decimal:
either
echo 19/5 - floor(19/5);
or
echo (19 % 5) / 5
will both return 0.8
Please try it-
$tempMod = (float)($x / $y);
$tempMod = ($tempMod - (int)$tempMod)*$y;
Depending on what language you're using, % may not be the modulus operator. I'll assume you're using PHP, in which case it is %.
From what I can see, there is no need to use floor() with integer modulus, it will always return an integer. You can safely remove it.
To me, it looks like it isn't the math that's giving you hell, it's the code around it. You'll need to post more code; the code you have listed is fine.
Edit:
You're not looking for the remainder, you're looking for the left over decimal value. It has no name.
$leftover = 19 / 5;
$leftover = $leftover - floor($leftover);
This should be what you're looking for.

Categories