Division by zero error while using modulus - php

Modulus operator is supposed to show the remainder. Like for echo(34%100) outputs 34. But why do i get a "Division by zero" error for this code echo(34%4294967296)

4294967296 is 2^32 and cannot be represented as 32 bit number - it wraps back to 0. If you use 64-bit version of PHP, it may work.
You might be able to use floating point modulus fmod to get what you want without overflowing.

https://bugs.php.net/bug.php?id=51731
2^31 is the largest integer you can get on Windows.
If you still want to mod large numbers, use bcmod.

I found this question searching for "division by zero error when using modulus", but the reason why was different.
Modulus (the % operator) will not work when the denomenator is is less than 1. using fmod() solves the problem.
Example:
$num = 5.1;
$den = .25;
echo ($num % $den);
// Outputs Warning: Division by zero
echo fmod($num, $den);
// Outputs 0.1
$num = 5.1;
$den = 1;
echo ($num % $den);
// Outputs 0, which is incorrect
echo fmod($num, $den);
// Outputs 0.1, which is correct

There's a lot of reports of mod getting wonky with large integers in php. Might be an overflow in the calculation or even in that number itself which is going to give you bugs. Best to use a large number library for that. Check out gmp or bcmath.

Related

PHP Division Float Value Issue

When I Try get remainder, It gives invalid value. I am trying to get remained of two decimal values and I get
3.4694469519536E-18
My Values are
$x=0.1; $y=0.005;
I tried the following:
echo $ed = fmod(0.1,0.005); OutPut:3.4694469519536E-18
echo $ed = ((floatval(0.1)) % (floatval(0.005)));
But getting
Warning: Division by zero
But Reality is 0.1 will be divide by 0.005 in 20 times. i.e. 0.1/0.005 = 20
The same function returns correct value when I use 10%1 = 0.
How can I get the exact remainder. ( I don't face the same issue in JQuery :) )
Check an Work Around: PHP Division Float Value WorkAround
The % operator just works on integers, so it truncates your floats to integers and tries to do 0 % 0, which results in a division by zero.
The only thing you can use is fmod(). The issue you face here is the typical floating point imprecision (the value is "nearly" zero). I'd consider to just ignore values smaller then 10^-15. There's no real alternative to this in PHP.
What you could try is doing the real division, then, with a bit of luck traces of the imprecision disappear. (like round(0.1 / 0.005) === 0.1 / 0.005)

Getting Remainder/% operator Throwing Error in php

I am new to php and was doing some mathematics and found this weird thing happening.
$numOfDiffChars = 62;
$id = 285355773910;
$remainder = $id % $numOfDiffChars;
echo "Remainder: ".$remainder." ID: ".$id." NumOfElems: ".$numOfDiffChars." ",($id - floor($id/$numOfDiffChars)*$numOfDiffChars);
The answer is as follows:
Remainder: 10 ID: 285355773910 NumOfElems: 62 26
which states that % operator gives the remainder 10 whereas mathematically its 26. What could be the reason for this? Is it just some error that I committed or is there a logic?
I am not quite sure, but if your using a 32-bit machine the problem could be that the integer $id is out of bound and therefore interpreted as a floating point.
http://php.net/manual/en/language.types.integer.php
have you tried fmod function find example on --->
http://www.php.net/manual/en/function.fmod.php
From php.net
Note that operator % (modulus) works just with integers (between -214748348 and 2147483647) while fmod() works with short and large numbers.

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.

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