Arithmetic operation not working php - php

I am trying to check if a number is odd or not but arithmetic operator % always returns 0.
$gst=($gst)*(100); // here $gst value is 155 after multiplication with 100
if(($gst%2)== 1)
{
$gst_receivable=(($gst-1)/2);
$gst_expense=(($gst-1)/2)+1;
}
else
{
$gst_receivable=($gst)/2;
$gst_expense=($gst)/2;
}
https://3v4l.org/8FQUf
But the above code always return 0 and runs the else part of the code.

You need to round() the variable before doing % 2 on it, because your float might still contain some rounding issues.
So change
if(($gst%2)== 1)
into
if(round($gst) % 2 == 1)

Related

Check if given number is Even, Odd or Neither in PHP? [duplicate]

This question already has answers here:
Test if number is odd or even
(20 answers)
Closed 7 years ago.
How can I get if a number is even or odd or neither (have decimal, like 1.5) with PHP? I know that there are operators like *, /, but they did not work.
Here's a try (of course it did not) (work that's just to find if it's a even number):
function even($n) {
return (($n/2)*2 == $n);
}
echo even(1); // true (should be false)
echo even(2); // true
How about
function even($n) {
if (!is_int($n)) {return 'n';}
return !($n % 2);
}
even(1); // false;
even(2); // true;
even(1.5); // 'n'
The danger here is that 'n' will evaluate as false if used as a boolean. It might be better to return some specific constants instead of true or false. The OP didn't specify what the return values should be.
It is pretty simple. modulo (%) is the operator you want, it determines if there would be a remainder if x is divided by y... for example (3 % 2 = 1) and (4 % 2 = 0).
This has been asked before too - pretty common question - you really just need to see if your number, $n % 2 is equal to 0.
php test if number is odd or even
Check if given number is integer first. And bitwise & to check if it is even or odd. Here is an example...
if (is_int($n)) {
if ($n & 1) {
echo 'Odd!';
} else {
echo 'Even!';
}
} else {
echo "Not a Integer!";
}
Hope this is helpful.
Use the modulo operator (%) to determine whether the integer is divisible by 2. You also need abs() to handle negative numbers, and is_int() to handle the fact that the modulo operator doesn't correctly handle floating point numbers. An example implementation follows:
function is_even($num) {
return is_int($num) && abs($num % 2) == 0;
}
function is_odd($num) {
return is_int($num) && abs($num % 2) == 1;
}
// this last one seems self-explanatory, but if you want it, here it is
function is_neither_even_nor_odd($num) {
return !is_even($num) && !is_odd($num);
}
// Tests: The following should all output true:
var_dump(
is_even(0),
is_even(2),
is_even(-6),
is_even(51238238),
is_odd(1),
is_odd(-1),
is_odd(57),
is_neither_even_nor_odd(1.5),
is_neither_even_nor_odd(2.5),
is_neither_even_nor_odd(-0.5),
is_neither_even_nor_odd(0.00000001)
);
Here's a demo.
is_numeric returns true if the given variable is a number
is_int returns true if the given variable is an integer
The modulor operator % can be used to determine if an integer is even or odd:
$num % 2 == 0 // returns true if even, false if odd

Odd and Even numbers (using & or %)

I've always used the following in order to find even and odd numbers:
if( $num % 2 ) { echo "odd"; }
if( !($num % 2) ) { echo "even"; }
But recently I stumbled upon with the following code that works exactly the same:
if( $num & 1 ) { echo "odd"; }
if( !($num & 1) ) { echo "even; }
What's the logic behind the "&" in the second method?
I went to check the PHP: Arithmetic Operators and the ampersand is not part of the options.
Thanks.
It is the bitwise-AND operator. Remember that in the computer, every integer is stored in binary form, and the lowest-significance binary digit is 2^0 == 1. So, every odd number will have the lowest binary digit = 1.
So, the bitwise AND operator compares your value bit-by-bit with the constant 1. Bits that are 1 in both operands are set to 1 in the result, but bits that are 0 in either operand are set to 0 in the result. The final result (which will be either 1 or 0) is coerced to boolean by PHP because you are using it as the clause in an if() statement.
There is a very good reason for checking evenness with & instead of %: Speed! The % operator requires a division operation so the remainder can be calculated, which is computationally much, much more expensive than just comparing the bits directly.
An example:
$num = 9; // 9 == 8 + 1 == 2^3 + 2^0 == 1001b
echo (string)($num & 1); // 1001b & 0001b = 0001b - prints '1'
$num = 10; // 10 == 8 + 2 == 2^3 + 2^1 == 1010b
echo (string)($num & 1); // 1010b & 0001b = 0000b - prints '0'
& is the binary AND.
The binary value of an odd number AND 1 will be 1, and the binary value of an even number AND 1 will be 0.
This happens because the binary value of an odd number always ends with 1 and the binary value of an even number ends with 0. So...
10101101 & 00000001 = 00000001 in the case of an odd number and,
10101100 & 00000000 = 00000000 in the case of an even number.

What is the most efficient way to make and odds system?

I'm trying to design an odds system that goes from 1-100, however it also uses 0-1 for rarer odds.
I was told I should use a floating point format, but I don't know that.
Basically I have..
if (mt_rand(1,1000)/100 == $odds) {} else if (mt_rand(1,100) == $odds) {}
however that only yields the same probability.
I looked up floating point format in the PHP manual, but the answers there couldn't help me.
See Odds to understand how to convert your odds to a probability. If you have odds of 4:1 then there is a 1/5 == 0.2 probability of the event. If your odds are .2:1 then there is a 5/6 (about .833) probability of the event happening. In general, if the odds are m:n against then the probability is n/(m+n).
Now, if you want to simulate whether an event occurs or not, you need to get a random floating point number between 0 and 1 then check if this is less than the probability of the event. You can use something like mt_rand(0,1000)/1000 to get a random number between 0 and 1.
Examples:
$odds1 = 4; // 4:1
$prob1 = 1/($odds1+1); // 1/5
if( mt_rand(0,1000)/1000 <= $prob1 ) {
// event happened
}
$odds2 = .2; // .2:1
$prob2 = 1/($odds2+1); // 5/6
if( mt_rand(0,1000)/1000 <= $prob2 ) {
// event happened
}
Floating point values are inexact. (See Why does `intval(19.9 * 100)` equal `1989`? and search: php floating point inexact.)
You cannot use == for floating point values. A simple 5/10 == 0.5 might already be wrong due to inherent precision loss.
You can either round numbers before comparison, your what I'd advise in your case, pre-convert floats into integers:
# 52 == 100*0.52
if (mt_rand(1,100) == round(100*$odds)) {
Instead of comparing 0.99 with another float, you convert your odds into an integer 99 and compare it with an integer random in the range 1 to 100. If odds already was an integer, not a float, then the *100 multiplication will already cut it out of that first (faux float) comparison.
if($odds < 1){
// floating point math here
if((float)mt_rand(0,100) / 100.0 < $odds){
echo "you're a float winner, harry";
}
}else{
if(mt_rand(0,100) < $odds){
echo "you're an int winner, harry!";
}
}

Odd behavior comparing doubles, two PHP double values aren't equivalent

I have two seemingly equal double values in PHP (at least when echoing them).
But when comparing them with double equals, for some reason, it evaluates to false. Are there any special considerations when performing this kind of comparison?
You shouldn't compare floating point numbers using the == operator.
See the big warning and explanation in the php manual
What will work is asserting that the two numbers are within a certain small distance of each other like this:
if(abs($a - $b) < 0.0001) {
print("a is mostly equal to b");
}
The reason is because of rounding errors due to floating point arithmetic performed after the decimals are converted to binary, then converted back to decimal. These back and forth conversions cause the phenomenon where 0.1 + 0.2 does not equal 0.3.
float and double should never be compared for equality: there are precision errors that will make two numbers different even if they seem equal (when they are printed out, they are usually rounded).
Proper way to compare is using some DELTA constant:
define(DELTA, 0.00001); // Or whatever precision you require
if (abs($a-$b) < DELTA) {
// ...
}
Also note that this is not PHP specific but also important in other languages (Java, C, ...)
Representation of floating point numbers in PHP (as well as in C and many other languages) is inexact. Due to this fact, seemingly equal numbers can in fact be different and comparison will fail. Instead, choose some small number and check that the difference is less than that, like:
if(abs($a-$b)<0.00001) {
echo "Equal!";
}
See also explanations in the PHP manual.
A small function i made, hope helps someone:
function are_doubles_equal($double_1, $double_2, $decimal_count) {
if (!$decimal_count || $decimal_count < 0) {
return intval($double_1) == intval($double_2);
}
else {
$num_1 = (string) number_format($double_1, $decimal_count);
$num_2 = (string) number_format($double_2, $decimal_count);
return $num_1 == $num_2;
}
}
Usage:
$a = 2.2;
$b = 0.3 + 1.9002;
are_doubles_equal($a, $b, 1); // true : 2.2 == 2.2
are_doubles_equal($a, $b, 1); // false : 2.2000 == 2.2002
Not the fastest way but convert to string before comparing:
if( strval($a) === strval($b) ){
// double values are exactly equal
}

Finding if a number is a power of 2

Just out of curiosity, how can you tell if a number x is a power of two (x = 2^n) without using recursion.
Thanks
One way is to use bitwise AND. If a number $x is a power of two (e.g., 8=1000), it will have no bits in common with its predecessor (7=0111). So you can write:
($x & ($x - 1)) == 0
Note: This will give a false positive for $x == 0.
Subtract 1 from the number, then and it with the original number. If the result is zero, it was a power of two.
if (((n-1) & n) == 0) {
// power of two!
}
(sorry, my PHP is rusty...)
If it's a power of 2? Well, one way is to convert it to binary, and verify the presence of only 1 1...:
$bin = decbin($number);
if (preg_match('/^0*10*$/', $bin)) {
//Even Power Of 2
}
For completeness, if the number is a float, you can test if it's a power of two by chacking if the mantissa is all zeros:
<?php
$number = 1.2379400392853803e27;
$d = unpack("h*", pack("d", $number)); $d = reset($d);
$isPowerOfTwo = substr($d, 0, 13) == "0000000000000";
var_dump($isPowerOfTwo); // bool(true)
Exercise for the reader: corner cases and big-endian machines.
In a binary equivalent of any decimal number which is a power of two will have only one occurrence of 1 in its binary equivalent.
<?php
$number = 4096;
$bin = decbin($number);
if ($number != 1 && substr_count($bin,1) == 1) {
echo "Yes";
} else {
echo "No";
}
?>
The top answer:
($x & ($x - 1)) == 0
seemed to have issues with larger numbers for me, this works well for larger numbers using the same logic but with GMP:
gmp_strval(gmp_and($x, gmp_sub($x, 1))) == 0
use mod 2 to determine if a number is a power of 2
def is_power_of_2(n):
if n == 0:
return False
while n % 2 == 0:
n = n / 2
return n == 1
I tried to implement the same thing without bitwise operators. Finally, I ended up with
return (fmod(log($x, 2), 1) === 0.00)
(In PHP)
Math.log(x)/Math.log(2) == Math.floor(Math.log(x)/Math.log(2))

Categories