PHP zero float returning true - php

I have a field in my mySQL db table of type decimal (15,4)
I've never experienced this before but if the value is 0.0000 my PHP if statement is returning true!
As a sanity check I even did:
if(0.0000) echo "Hello World";
And sure enough, Hello World echo'd out. What the hell is going on? Anybody got any ideas?

If it's a float value coming out from DB it will be treated like a string, not like a numeric value. You can try something this:
if(floatval($value) > 0) { ... }
Where $value contains the value from DB.

I think the problem is you got a string "0.0000" from db but not 0.0000.
Try again with:
if ((int)$your_value) echo "Hello World";

I don't have this behavior on my PHP version (5.3.3).
I suggest casting the number to bool before doing the check: if ((bool) $float).

I know it's been a long time since this question was opened but I thought it might help out someone else.
A float is actual an approximation of the Real Number. You will find that not all Real numbers can be represented by a float. This might be the reason why you are getting unexpected results. You should have a read of
http://php.net/manual/en/language.types.float.php.
If however you need higher precision you should look at using the BC Math lib's http://php.net/manual/en/ref.bc.php.

Related

PHP round() function does not round the number

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.

if statement based on date()

OK, I am new to PHP coding and I tried to look over previous questions here so if I missed something, please let me know.
Using a PHP if statement, I am trying to have one known working PHP/MySQL codeset run between the hours of 11pm to 8am and another known working PHP/MySQL codeset the rest of the day.
Please let me know if you need any further elaboration to understand my question and thank you for the assistance!
<?php
if (date('H')>=23 || date('H')<=08) {
Runs a PHP/MySQL query that is know to work. The IF statement never runs this code.
}
else
{
Runs another PHP/MySQL query that is know to work. The IF statement always returns FALSE and runs this code.
}
?>
date('H')<=08
A number (not a quoted string) with a leading zero is treated as an octal value.... 08 is invalid as an octal value, and is treated as a numeric zero, so date('H')<=08 equivalent to date('H')<=0
EDIT
Either allow PHP's loose typing to convert your Hour string to an integer:
date('H')<=8
or use loose type comparison for both sides of the comparison (with 08 as a quoted string, which will loose cast to decimal 8):
date('H')<='08'
or use date format mask 'G'
date('G')<=8

Integer string comparison are equal (PHP bug?)

I'm comparing two strings like so:
<?php
$Str1 = '111122223333444455556666';
$Str2 = '111122223333444455557777';
if($Str1 != $Str2){
// Do something
} else {
// Do something else
}
?>
Obviously, $Str1 is not the same as $Str2, but still always executes the else-block. I know that I should simply use === or !== to compare here, but I'm wondering why (basically) any other value I try does in fact evaluate the way it's expected to.
I also read this in the documentation "If the string does not contain any of the characters '.', 'e', or 'E' and the numeric value fits into integer type limits (as defined by PHP_INT_MAX), the string will be evaluated as an integer.", so I'm guessing it should not be below or the same as the value of PHP_INT_MAX (which is by far less than the strings I'm evaluating above) - assuming that's what they mean by "fits into". So why are the strings above being evaluated as being the same? Could it possibly be a PHP bug or is there something I'm missing?
I'm using PHP version 5.3.8 since yesterday, coming from PHP 5.3.6. Running on Windows XP.
What is happening here is that the numbers are cast to floats (as they don't fit into ints) and the floats happen to be the same. See the PHP source.
This script shows that the parsed floats indeed have the same value.
That's what it looks like, if I do this:
$Str1 = '111122223333444455556666 ';
$Str2 = '111122223333444455557777 ';
It comes out fine (note the space)
So it must be converting to number and not seeing the difference because of length
One could get the thought that PHP is bit relaxed in these conversions?!
Then again, do you rather want good old strict type-checking?
Not as advanced as above, but still enough to grab an hour of my time recently.
<?
$a_var = 0;
if ($a_var=="WHATEVER")
echo "WATCH OUT! This will be printed!";
//- as "whatever" is converted to an int
if ((string)$a_var=="WHATEVER")
echo "OK, this will of course not be printed!";
$a_var = "0";
if ($a_var=="WHATEVER")
echo "OK, this will of course also not be printed!";
?>
Conclusion: BEWARE of the automated casting in PHP.
It may play tricks on you now and then, and bugs may be very hard to track.
Explicit casting one time too many may be smarter at times, rather than relying on our great PHP understanding. ;-)
Use
if (strcmp($Str1, $Str2) == 0) {
//equal
} else {
//not equal
}
As mentioned in https://docstore.mik.ua/orelly/webprog/php/ch04_06.htm, first compare the two as String and then compares to 0 is there're equal.

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.

Is there a PHP calculation which could result in a -0?

I am having trouble with a complex script which sometimes (About 2 or 3 times while calulating about 90'000 values), generates a '-0' and writes it into the database. I suspect it's a string (The values which are calulated can result in integers, floats or strings.)*
Is there any PHP calculation which might result in a '-0'?
* = Oh, how I miss strong typing sometimes...
Rounding a negative number toward positive infinity, as ceil() does, can produce -0.
echo ceil(-.7);
// -0
The same result comes with, e.g., round(-.2).
Both of these will resolve to true:
(-0 == 0)
(ceil(-.7) == 0)
While these will resolve to true and false, respectively:
(-0 === 0)
(ceil(-.7) === 0)
Edit: An interesting (and implemented) rfc can be read here.
As Gurdas says, you can have your strong typing in the database. That aside, I don't know the answer to your question but I know how would I approach the problem.
The problem, as I understand it, is that you don't know in which cases you get the '-0', which is a valid floating point representation of 0, by the way. So you have to find in which cases you are getting that. I'd take one of two routes:
Use Xdebug, raise an error in the database insertion code when the value is '-0' to get a stack_trace with arguments (use xdebug.collect_params=1)
Create an empty string at the beginning of the script, populating it with all the operations and operands being done as they are, with the result and line. Afterwards, in the insertion clause add an if ($value == '-0') { print $string; }

Categories