PHP round() function does not round the number - php

It looks like PHP round() does not behave as expected. Look at the following code:
log_rec("BEFORE ROUNDING","x", $x);
$x = round($x, 3);
log_rec("AFTER ROUNDING","x", $x);
where log_rec() is simply a function of mine to write a record in a log file,
and $x value is initially set to 3.339999999999999857891452847979962825775146484375.
I expect $x to be 3.34 after rounding.
Here is the result in log file:
▶"BEFORE ROUNDING"■"x"■3.339999999999999857891452847979962825775146484375■
▶"AFTER ROUNDING"■"x"■3.339999999999999857891452847979962825775146484375■
No change. What am I doing wrong? I am using PHP 7.4.26.
NOTE: I need to round the number, that is, to obtain another float number. So, number_format() is not a solution.
UPDATE
I decided to use a different approach, that is to use
log_rec("BEFORE ROUNDING","x", $x);
$x= intval(100 * $x)/100;
log_rec("AFTER ROUNDING","x", $x);
I expected now
▶"BEFORE ROUNDING"■"x"■3.339999999999999857891452847979962825775146484375■
▶"AFTER ROUNDING"■"x"■3.34■
but I still get
▶"BEFORE ROUNDING"■"x"■3.339999999999999857891452847979962825775146484375■
▶"AFTER ROUNDING"■"x"■3.339999999999999857891452847979962825775146484375■
Now I am totally confused. This is a sequence of three well defined instructions. No other code should create some collateral effect.
Any idea?
PS: WHERE THE NUMBER COMES FROM?
Someone asked where that big number comes from.
From a JSON file. What is strange is that that number in JSON is 3.334, but after json_decode() something strange happens: if I use var_dump() I get 3.334 but if I use print_r() I get that big number.

Related

FMOD in PHP results not being seen as equal to their float equivalent

So I understand that FMOD gives some wacky answers sometimes because its sort of approximate.
But even given that I'm struggling to utilize the answers it throws up later-on in the code.
For instance, fmod(16,1.6) gives us 1.6 rather than 0, that's fine. In the following code, echoing $goodfit prints 1.6 but hurray doesn't print.
$getLength = 16;
$goodFit = fmod($getLength, 1.6);
echo $goodFit;
if ($goodFit === 1.6){
echo hurray;
}
I've tried double equation signs instead of triple incase it was a data type problem and I've tried rounding the $goodfit equation to one decimal place.
All seems a little odd.
I'm just trying to make a bit of code that triggers if a division was exact.

PHP equivalent for Excel's COMBIN(N,K) function?

I am aware that the function may be computed manually using factorials, the problem is that larger numbers will not calculate properly.
For example, if I input COMBIN(1500,5) in MS Excel it will return 62,860,358,437,800 as it should. But if I try to calculate it manually, even in Excel I will get a #NUM! error when I try to first find the factorial of 1500. The manual formula would be
1500!/5!(1500-5)!
I find it curious that Excel's COMBIN function calculates properly yet the manual way returns an error. In short, I am wondering if there is an equivalent of this function in PHP? I have already tried manually computing using gmp_fact and as with Excel, it returns error (NaN).
Thanks
Your calculation is failing because you're quickly overflowing the Integer data type, which is probably just 32-bits on your system. You could use the arbitrary precision math functions to get around that problem:
http://www.php.net/manual/en/ref.gmp.php
If gmp_fact(...) seems to be returning errors or bad results, you're probably passing it a bad value or assuming it's result is a basic numeric type. You'll want to use something like gmp_strval to convert the returned GMP resource into something readable when you're done performing calculations.
Example:
$a = gmp_fact(1500);
$b = gmp_fact(5);
$c = gmp_fact(1500-5);
$result = gmp_div($a,(gmp_mul($b,$c)));
echo gmp_strval($result);

PHP Ignoring Digits to the Right of the Decimal Point in Equation

I have a variable $x whose value is read in from an XML file. The value being read from the XML is 1.963788, nothing more, nothing less. When I output $x, I see that the value in $x is in fact 1.963788. All is right with the world.
But then when I use x in an equation such as
$pl = $x*125.0-200.0;
The value of $pl ends up being -75. For whatever reason, PHP seems to be ignoring, or just getting rid of, the digits to the right of the decimal point in $x, which makes $x contain 1. I thought maybe there was a snowball's chance in hell that this occurred in other languages too, so I wrote it up in C++ and, big surprise, I get the right answer of 45.4735.
Anyone ever encountered this before or know what's going on? Thanks.
Have you tried using floatval?
Maybe PHP interprets your number as a string and the standard conversion just casts it to integer.
It probably is due to the fact that $x is being interpreted as a string, and converted to an integer and not a float value.
Try:
$pl = (float) $x * 125.0 - 200.0;
Your number appears to have failed casting as a float. If I use '1,963788' I get your result. If I use '2,963788' I receive a result of 50. According to the PHP docs for intval (and that's what it appears PHP is trying to cast this as, an integer):
Strings will most likely return 0 although this depends on the leftmost characters of the string. The common rules of integer casting apply.
Check the value $x actually has carefully. It may not be what you expect since PHP seems to disagree that it is, in fact, a float or it would have typed it as such.
Just before you compute $pl, do a var_dump on $x to see what is the actual value stored in it. I've tried your code and it is returning the correct value 45.4735, so I might not be PHP's fault.

PHP - Why does my computation produce a different result when I assign it to a variable?

I want to round a number to a specific number of significant digits - basically I want the following function:
round(12345.67, 2) -> 12000
round(8888, 3) -> 8890
I have the following, but there's a strange problem.
function round_to_sf($number, $sf)
{
$mostsigplace = floor(log10(abs($number)))+1;
$num = $number / pow(10, ($mostsigplace-$sf));
echo ($number / pow(10, ($mostsigplace-$sf))).' '.$num.'<BR>';
}
round_to_sf(41918.522, 1);
Produces the following output:
4.1918522 -0
How can the result of a computation be different when it's assigned to a variable?
Using the commenting-out binary search method of debugging, I narrowed this down.
Apparently the following line, in another function, in a totally different file even, is the problem.
$diff = date_diff(new DateTime($lastdate), new DateTime("NOW"));
If I comment that out, I get a correct result from my rounding function.
Can anyone tell me what the .... is going on here? This had me ripping my hair out for a day. It also caused other bugs that looked like memory stomps - I'd run a calculation that should produce a float foo, and foo would get used in other calculations that produced correct output, but echoing foo would show A.KIPGGGGGGGGG.

round in PHP shows scientific notation instead of full number

I'm trying to do an echo of a variable containing 1400000.
so there is written: echo round(1400000);
this gives 1,4E+6 instead of the full number.
Anybody an idea on how to display it fully?
It seems that round was the problem.
I changed it with number_format() and this does the job just fine.
Thanks Aron and Paul for the answers.
Related to your question, I also came across this comment on the PHP website.
PHP switches from the standard decimal
notation to exponential notation for
certain "special" floats. You can see
a partial list of such "special"
values with this:
for( $tmp = 0, $i = 0; $i < 100; $i++ )
{
$tmp += 100000;
echo round($tmp),"\n";
}
So, if you add two floats, end up with
a "special" value, e.g. 1.2E+6, then
put that value unmodified into an
update query to store the value in a
decimal column, say, you will likely
get a failed transaction, since the
database will see "1.2E+6" as varchar
data, not decimal. Likewise, you will
likely get an XSD validation error if
you put the value into xml.
I have to be honest: this is one of
the strangest things I have seen in
any language in over 20 years of
coding, and it is a colossal pain to
work around.
It seems there has not been a "real" fix yet, but judging from the comments in the bug report Paul Dixon referered to earlier, his solution seems to work.
Possibly related to this bug report, so you could try
printf("%d", $myvar);

Categories