I'm reading data from a text file and performing some basic math. This is how things should work:
// no warning, expected result N/A
$dividend = 100;
$divisor = 0.0;
if (!empty($dividend) && !empty($divisor))
{
$quotient = $dividend/$divisor;
} else {
$quotient = 'N/A';
}
echo $quotient;
This is how things are actually happening.
// yeilds division by zero warning
$dividend = 100;
$divisor = '0.0';
if (!empty($dividend) && !empty($divisor))
{
$quotient = $dividend/$divisor;
} else {
$quotient = 'N/A';
}
echo $quotient;
I'm getting a division by zero warning when a value in the text file is read as '0.0', which empty() sees as non-empty, when it actually empty.
What's the best way to test that '0.0' is actually 0?
Typecast $divisor to float: $divisor = (float)'0.0';
You'll want to cast to float (or use floatval()) in your condition statement. This leaves your values untouched in case you need other data from your variables, such as trailing text:
$dividend = 100;
$divisor = '0.0';
if ((float)$dividend && (float)$divisor) //both are non-zero
{
$quotient = $dividend/$divisor;
} else { //one or the other are zero
$quotient = 'N/A';
}
echo $quotient;
However consider only checking $divisor for zero.
Cast it to an int;
$divisor = (int) '0.0';
i think quotient should be zero if divisior is zero.
So you get a result in the following operations instead a N/A.
I always resolve it like this:
$quotient = ($divisor == 0) ? 0 : ($divident/$divisor);
it should work for "0.0", too.
Related
My code is showing an error in the line commented below saying:
ErrorException A non-numeric value encountered
The input variable receives an asterisk character and runs through my if instead of stopping at the first iteration. Could you help me find out the reason for the error or tell me the command to exit if after the first if iteration?
$minute = '*';
$pos1 = strpos($minute, '*');
$pos2 = strpos($minute, ',');
$pos3 = strpos($minute, '-');
$pos4 = strpos($minute, '/');
if (true == $pos1) {
$operator = '*';
} elseif (true == $pos2) {
$operator = ',';
} elseif (true == $pos3) {
$operator = '-';
} elseif (true == $pos4) {
$operator = '/';
} else {
$minute_atual = Carbon::now->format('i');
if ($minute < $minute_current) {
$minute = 60 - ($minute_current - $minute); // The error message says it is on that line
$operator = $ minute;
} elseif ($minute_current == $minute) {
$minute = '0';
$operator = $minute;
} else {
$minute = $minute - $minute_current;
$operator = $minute;
}
}
strpos is notorious for that error.
Indeed
$minute = "*";
$pos1 = strpos($minute, '*');
var_dump($pos1);
// 0 because this is the first (0th) character
so the test true == 0 fails
Use strict inequality $pos0 !== false instead
Function reference : https://www.php.net/manual/en/function.strpos
See the warning in the "return value" section.
$minute = '*';
This is a string. And php can't apply numeric operations over it. I don't see if you are assigning a numeric value to it before the subtraction.
Basically you are trying to do "number - (number - string)". Probably you are missing some part of your logic.
Also you don't need to set priority over the operations if they are subtraction or addition.
60 - $minute_current - $minute
Will give you the same result. Of course if $minute is integer.
And also I strongly recommend to avoid weak comparison, use ===, !== instead. So you know exactly what you are doing
I am trying to slightly increment a value based on the number of decimals it has.
For example if the value is 1.2 I would increase it by 0.1, 12.345 by 0.001, 12.345678 by 0.000001, etc.
I currently have a long implementation using a chain of if, else if. I know this is not the most efficient way and a loop can be used, but I was unsure of how to structure the loop. I tried using the PHP substr_replace function, but I could not get it to work for this.
Is there another way I can structure a loop to reduce my lines of code and be more efficient?
Here is my php code so far:
$valueOne = 12.345678;
// get amount of decimals
$decimal = strlen(strrchr($valueOne, '.')) -1;
/*
this also works for finding how many decimals
$test = floatval($valueOne);
for ( $decimal_count = 0; $test != round($test, $decimal_count); $decimal_count++ );
echo $decimal_count;
*/
// see value before change
echo $valueOne;
if ($decimal == "1") {
$valueOne = $valueOne + 0.1;
}
else if ($decimal == "2") {
$valueOne = $valueOne + 0.01;
}
else if ($decimal == "3") {
$valueOne = $valueOne + 0.001;
}
// etc ...
// see value after change
echo $valueOne;
/*
i tried messing around with using a loop, but did not have much luck
$start = 0.1;
$count = 0;
$position = 2;
while ($count != $decimal) {
echo substr_replace($start, 0, $position, 0) . "<br />\n";
$count++;
//$position++;
}
*/
Get the number of digits after the decimal. Then create a number with a decimal point, one less 0, followed by 1, to get the amount to add.
$valueOne = 12.345678;
// get amount of decimals
$decimal = strlen(strrchr($valueOne, '.')) -1;
// see value before change
echo $valueOne . "<br>\n";
// Get amount to add
$increment = '.' . str_repeat('0', $decimal-1) . '1';
$valueOne += $increment;
echo $valueOne;
Get the number of decimals
Multiply by the appropriate factor so the number is now an integer
Increment by 1
Divide by the same factor to get back to the original number (properly incremented)
function increment($number){
// get amount of decimals
$decimal = strlen(strrchr($valueOne, '.')) -1;
$factor = pow(10,$decimal);
$incremented = (($factor * $number) + 1) / $factor;
return $incremented;
}
I have the following calculation:
$this->count = float(44.28)
$multiple = float(0.36)
$calc = $this->count / $multiple;
$calc = 44.28 / 0.36 = 123
Now I want to check if my variable $calc is integer (has decimals) or not.
I tried doing if(is_int()) {} but that doesn't work because $calc = (float)123.
Also tried this-
if($calc == round($calc))
{
die('is integer');
}
else
{
die('is float);
}
but that also doesn't work because it returns in every case 'is float'. In the case above that should'n be true because 123 is the same as 123 after rounding.
Try-
if ((string)(int) $calc === (string)$calc) {
//it is an integer
}else{
//it is a float
}
Demo
As CodeBird pointed out in a comment to the question, floating points can exhibit unexpected behaviour due to precision "errors".
e.g.
<?php
$x = 1.4-0.5;
$z = 0.9;
echo $x, ' ', $z, ' ', $x==$z ? 'yes':'no';
prints on my machine (win8, x64 but 32bit build of php)
0.9 0.9 no
took a while to find a (hopefully correct) example that is a) relevant to this question and b) obvious (I think x / y * y is obvious enough).
again this was tested on a 32bit build on a 64bit windows 8
<?php
$y = 0.01; // some mambojambo here...
for($i=1; $i<31; $i++) { // ... because ...
$y += 0.01; // ... just writing ...
} // ... $y = 0.31000 didn't work
$x = 5.0 / $y;
$x *= $y;
echo 'x=', $x, "\r\n";
var_dump((int)$x==$x);
and the output is
x=5
bool(false)
Depending on what you're trying to achieve it might be necessary to check if the value is within a certain range of an integer (or it might be just a marginalia on the other side of the spectrum ;-) ), e.g.
function is_intval($x, $epsilon = 0.00001) {
$x = abs($x - round($x));
return $x < $epsilon;
};
and you might also take a look at some arbitrary precision library, e.g. the bcmath extension where you can set "the scale of precision".
You can do it using ((int) $var == $var)
$var = 9;
echo ((int) $var == $var) ? 'true' : 'false';
//Will print true;
$var = 9.6;
echo ((int) $var == $var) ? 'true' : 'false';
//Will print false;
Basically you check if the int value of $var equal to $var
round() will return a float. This is because you can set the number of decimals.
You could use a regex:
if(preg_match('~^[0-9]+$~', $calc))
PHP will convert $calc automatically into a string when passing it to preg_match().
You can use number_format() to convert number into correct format and then work like this
$count = (float)(44.28);
$multiple = (float)(0.36);
$calc = $count / $multiple;
//$calc = 44.28 / 0.36 = 123
$calc = number_format($calc, 2, '.', '');
if(($calc) == round($calc))
die("is integer");
else
die("is not integer");
Demo
Ok I guess I'am pretty late to the party but this is a alternative using fmod() which is a modulo operation. I simply store the fraction after the calculation of 2 variables and check if they are > 0 which would imply it is a float.
<?php
class booHoo{
public function __construct($numberUno, $numberDos) {
$this->numberUno= $numberUno;
$this->numberDos= $numberDos;
}
public function compare() {
$fraction = fmod($this->numberUno, $this->numberDos);
if($fraction > 0) {
echo 'is floating point';
} else {
echo 'is Integer';
}
}
}
$check= new booHoo(5, 0.26);
$check->compare();
Eval here
Edit: Reminder Fmod will use a division to compare numbers the whole documentation can be found here
if (empty($calc - (int)$calc))
{
return true; // is int
}else{
return false; // is no int
}
Try this:
//$calc = 123;
$calc = 123.110;
if(ceil($calc) == $calc)
{
die("is integer");
}
else
{
die("is float");
}
you may use the is_int() function at the place of round() function.
if(is_int($calc)) {
die('is integer');
} else {
die('is float);
}
I think it would help you
A more unorthodox way of checking if a float is also an integer:
// ctype returns bool from a string and that is why use strval
$result = ctype_digit(strval($float));
I am having confusion in if statement
I have like
if(hello==0 || bye==0)
{
echo 'error';
}
but if
hello==1 || bye==0 OR hello==0 || bye==1
then it should echo 'fine';
is their any process by which i can put this type of condition in if statement ??
EDIT
$numbers1=0;
$numbers2=0;
if(numbers1==0 || numbers2==0){
$percentage1 = ($numbers2 / ($numbers2 + $numbers1)) * 100;
$parcentage2 = ($numbers1 / ($numbers2 + $numbers1)) * 100;
}
This is why i can do fine clause as main statement
Warning: Division by zero
It looks like you want:
if($hello==1 || $bye==1)
{
echo 'fine';
}
else
{
echo 'error';
}
Oh, you could just do
if (($numbers1 + $numbers2) != 0)
echo 'fine';
else
echo 'error';
to make sure the result of $numbers1 and $numbers2 isn't zero before dividing by it.
Look carefully at your conditions.
This works if there are no other possible values other than 0 or 1 (best to use a bool in this case probably)
if($hello==0 || $bye==0)
{
echo 'error';
}
else
{
echo 'fine';
}
If you want to guard against a null value then just use the isset() in your conditional.
Looks like you want to avoid division by zero which can occur when both $number1 and $number2 are zero.
if (0 === $number1 && 0 === $number2)
{
// division by zero
}
else
{
// perform your calculation
}
One thing you did not make clear: Could either or both $number1 and $number2 be negative? If yes, then you might want to consider the condition where the sum of the numbers are zero (as per #sbat's suggestion).
if( $numbers1!= 0 || $numbers2 != 0){
$percentage1 = ($numbers2 / ($numbers2 + $numbers1)) * 100;
$parcentage2 = ($numbers1 / ($numbers2 + $numbers1)) * 100;
}
else
{
echo 'error';
}
Note that you are missing the dollar sign before numbers1 and numbers2 variables in your if statement. Good Luck.
I have a game development project and I have specific character one of the skill of the character is that it has a 10% chance of doubling its attack.
Question: How can I trigger it?
I hope i understand ure question:
<?php
$random = rand(1,10);
if(($random == 1) || ($random == 2) || ($random == 3))
$value += $value;
?>
Here you have a 30% chance to hit 1, 2 or 3.. and if its hit then your value gets doubled.
Ok now for your Update u just need a 10% chance? But okay:
<?php
$random = rand(1,10);
if($random == 1)
$value += $value;
?>
function doubleHit($percentChance = 30)
{
if (mt_rand(1,100) <= $percentChance) {
return true;
}
return false;
}
var_dump(doubleHit(35)); // will return either true / false
Note that this is only pseudorandom. Also note that this is faster / better than rand().
For example this code will double the value theoretically one in three times? It's hard for me to understand you.
$value = 200;
if (rand(1,3)===1) {
$value*=2;
}
Or maybe this, for percents:
$value = 200;
$percent = 30;
$chance = rand(1, 100);
if ($chance <= $percent) {
$value *= 2;
}