opposite of binary number - php

I have a binary number 11000 i need to flip the number to get the answer 00111
and i need the result in PHP, i did it using the for loop but how can i do it using bitwise operator i think we can do it using ^ operator here is the PHP solution:
function getIntegerComplement($n) {
// $n is a decimal number
$binary = decbin($n);
$arr = str_split($binary);
$complement = "";
foreach($arr as $i)
$complement .= ($i == 0) ? (1) : (0);
}
any help would be appriciated

If you negate the whole int, you'll get a negative number: as int consists of 32 bits (usually), and all of them will be negated. And when the 1-st bit becomes 1, php will treat it as a negative number. And you want to negate only last 5 bits. Here it is done, using the $val + $mask (mod 2):
<?php
$val = bindec('11000');
$mask = bindec('11111');
$val = $val ^ $mask;
print sprintf('%05d', decbin($val));
Prints 00111, just as expected.

Use the bitwise NOT operator:
return ~$n;

Use "NOT" ( ~ ).
It reverses the supplied value:
function getIntegerComplement($n) {
return ~$n;
}
More info here: http://php.net/manual/en/language.operators.bitwise.php
~ $a ---> Not: Bits that are set in $a are not set, and vice versa.

Related

Why does PHP not recognize the sequence of digits from PHP_INT_MIN as an integer

With
var_dump(PHP_INT_MIN);
//int(-9223372036854775808)
I get the number -9223372036854775808. If I assign this number to a variable, it is of the float type.
$n = -9223372036854775808;
var_dump($n);
//float(-9.2233720368548E+18)
This gives me integers:
$n = PHP_INT_MIN;
var_dump($n);
//int(-9223372036854775808)
and
$n = intval("-9223372036854775808");
var_dump($n);
//int(-9223372036854775808)
and
$n = sscanf("-9223372036854775808","%d")[0];
var_dump($n);
//int(-9223372036854775808)
Why does PHP give me a float type for -9223372036854775808 ?
Because the minus sign is not part of the syntax of a number in source code, it's the unary negation operator. So
$n = -9223372036854775808;
is treated like
$n = -(9223372036854775808);
But 9223372036854775808 is larger than PHP_INT_MAX, so it's parsed as a float, and then negated.

How can I do math with intergers close to 32bit max and floats between 0 and 2^32 in PHP? [duplicate]

To use modular exponentiation as you would require when using the Fermat Primality Test with large numbers (100,000+), it calls for some very large calculations.
When I multiply two large numbers (eg: 62574 and 62574) PHP seems to cast the result to a float. Getting the modulus value of that returns strange values.
$x = 62574 * 62574;
var_dump($x); // float(3915505476) ... correct
var_dump($x % 104659); // int(-72945) ... wtf.
Is there any way to make PHP perform these calculations properly? Alternatively, is there another method for finding modulus values that would work for large numbers?
For some reason, there are two standard libraries in PHP handling the arbitrary length/precision numbers: BC Math and GMP. I personally prefer GMP, as it's fresher and has richer API.
Based on GMP I've implemented Decimal2 class for storing and processing currency amounts (like USD 100.25). A lot of mod calculations there w/o any problems. Tested with very large numbers.
use this
$num1 = "123456789012345678901234567890";
$num2 = "9876543210";
$r = mysql_query("Select #sum:=$num1 + $num2");
$sumR = mysql_fetch_row($r);
$sum = $sumR[0];
have you taken a look at bcmod()? php has issues with integers over 2^31 - 1 on 32 bit platforms.
var_dump(bcmod("$x", '104659') ); // string(4) "2968"
I suggest you try BigInteger. If that doesn't work out, you may use SWIG to add C/C++ code for the big integer calculations and link it into your code.
I wrote a very small code for you that will surely work in case of big numbers-
<?php
$x = gmp_strval(gmp_mul("62574","62574")); // $x="3915505476"
$mod=gmp_strval(gmp_mod($x,"104659")); //$mod="2968"
echo "x : ".$x."<br>";
echo "mod : ".$mod;
/* Output:
x : 3915505476
mod : 2968
*/
?>
You simply have to use strings for storing big numbers and to operate on them use GMP functions in PHP.
You may check some good GMP functions in the official PHP manual here-
http://php.net/manual/en/ref.gmp.php
I found another solution, but the number will be stored as a string. As soon as you cast it back to a numeric, you'll be restricted to the precision of the underlying platform. On a 32 bit platform, the largest int you can represent as an int type is 2,147,483,647:
/**
* #param string $a
* #param string $b
* #return string
*/
function terminal_add($a,$b)
{
exec('echo "'.$a.'+'.$b.'"|bc',$result);
$ret = "";
foreach($result as $line) $ret .= str_replace("\\","",$line);
return $ret;
}
// terminal_add("123456789012345678901234567890", "9876543210")
// output: "123456789012345678911111111100"
$x = 62574 * 62574;
// Cast to an integer
$asInt = intval($x);
var_dump($asInt);
var_dump($asInt % 104659);
// Use use sprintf to convert to integer (%d), which will casts to string
$asIntStr = sprintf('%d', $x);
var_dump($asIntStr);
var_dump($asIntStr % 104659);
<?php
function add($int1,$int2){
$int1 = str_pad($int1, strlen($int2), '0', STR_PAD_LEFT);
$int2 = str_pad($int2, strlen($int1), '0', STR_PAD_LEFT);
$carry = 0;
$str = "";
for($i=strlen($int1);$i>0;$i--){
$var = $int1[$i-1] + $int2[$i-1] + $carry;
$var = str_pad($var, 2, '0', STR_PAD_LEFT);
$var = (string) $var;
$carry = $var[0];
$str = $str . $var[1];
}
$res = strrev($str.$carry);
echo ltrim($res,"0");
}
add($int1,$int2);
?>

How to get number of digits in both right, left sides of a decimal number

I wonder if is there a good way to get the number of digits in right/left side of a decimal number PHP. For example:
12345.789 -> RIGHT SIDE LENGTH IS 3 / LEFT SIDE LENGTH IS 5
I know it is readily attainable by helping string functions and exploding the number. I mean is there a mathematically or programmatically way to perform it better than string manipulations.
Your answers would be greatly appreciated.
Update
The best solution for left side till now was:
$left = floor(log10($x))+1;
but still no sufficient for right side.
Still waiting ...
To get the digits on the left side you can do this:
$left = floor(log10($x))+1;
This uses the base 10 logarithm to get the number of digits.
The right side is harder. A simple approach would look like this, but due to floating point numbers, it would often fail:
$decimal = $x - floor($x);
$right = 0;
while (floor($decimal) != $decimal) {
$right++;
$decimal *= 10; //will bring in floating point 'noise' over time
}
This will loop through multiplying by 10 until there are no digits past the decimal. That is tested with floor($decimal) != $decimal.
However, as Ali points out, giving it the number 155.11 (a hard to represent digit in binary) results in a answer of 14. This is because as the number is stored as something like 155.11000000000001 with the 32 bits of floating precision we have.
So instead, a more robust solution is needed. (PoPoFibo's solutions above is particularly elegant, and uses PHPs inherit float comparison functions well).
The fact is, we can never distinguish between input of 155.11 and 155.11000000000001. We will never know which number was originally given. They will both be represented the same. However, if we define the number of zeroes that we can see in a row before we just decide the decimal is 'done' than we can come up with a solution:
$x = 155.11; //the number we are testing
$LIMIT = 10; //number of zeroes in a row until we say 'enough'
$right = 0; //number of digits we've checked
$empty = 0; //number of zeroes we've seen in a row
while (floor($x) != $x) {
$right++;
$base = floor($x); //so we can see what the next digit is;
$x *= 10;
$base *= 10;
$digit = floor($x) - $base; //the digit we are dealing with
if ($digit == 0) {
$empty += 1;
if ($empty == $LIMIT) {
$right -= $empty; //don't count all those zeroes
break; // exit the loop, we're done
}
} else {
$zeros = 0;
}
}
This should find the solution given the reasonable assumption that 10 zeroes in a row means any other digits just don't matter.
However, I still like PopoFibo's solution better, as without any multiplication, PHPs default comparison functions effectively do the same thing, without the messiness.
I am lost on PHP semantics big time but I guess the following would serve your purpose without the String usage (that is at least how I would do in Java but hopefully cleaner):
Working code here: http://ideone.com/7BnsR3
Non-string solution (only Math)
Left side is resolved hence taking the cue from your question update:
$value = 12343525.34541;
$left = floor(log10($value))+1;
echo($left);
$num = floatval($value);
$right = 0;
while($num != round($num, $right)) {
$right++;
}
echo($right);
Prints
85
8 for the LHS and 5 for the RHS.
Since I'm taking a floatval that would make 155.0 as 0 RHS which I think is valid and can be resolved by String functions.
php > $num = 12345.789;
php > $left = strlen(floor($num));
php > $right = strlen($num - floor($num));
php > echo "$left / $right\n";
5 / 16 <--- 16 digits, huh?
php > $parts = explode('.', $num);
php > var_dump($parts);
array(2) {
[0]=>
string(5) "12345"
[1]=>
string(3) "789"
As you can see, floats aren't the easiest to deal with... Doing it "mathematically" leads to bad results. Doing it by strings works, but makes you feel dirty.
$number = 12345.789;
list($whole, $fraction) = sscanf($number, "%d.%d");
This will always work, even if $number is an integer and you’ll get two real integers returned. Length is best done with strlen() even for integer values. The proposed log10() approach won't work for 10, 100, 1000, … as you might expect.
// 5 - 3
echo strlen($whole) , " - " , strlen($fraction);
If you really, really want to get the length without calling any string function here you go. But it's totally not efficient at all compared to strlen().
/**
* Get integer length.
*
* #param integer $integer
* The integer to count.
* #param boolean $count_zero [optional]
* Whether 0 is to be counted or not, defaults to FALSE.
* #return integer
* The integer's length.
*/
function get_int_length($integer, $count_zero = false) {
// 0 would be 1 in string mode! Highly depends on use case.
if ($count_zero === false && $integer === 0) {
return 0;
}
return floor(log10(abs($integer))) + 1;
}
// 5 - 3
echo get_int_length($whole) , " - " , get_int_length($fraction);
The above will correctly count the result of 1 / 3, but be aware that the precision is important.
$number = 1 / 3;
// Above code outputs
// string : 1 - 10
// math : 0 - 10
$number = bcdiv(1, 3);
// Above code outputs
// string : 1 - 0 <-- oops
// math : 0 - INF <-- 8-)
No problem there.
I would like to apply a simple logic.
<?php
$num=12345.789;
$num_str="".$num; // Converting number to string
$array=explode('.',$num_str); //Explode number (String) with .
echo "Left side length : ".intval(strlen($array[0])); // $array[0] contains left hand side then check the string length
echo "<br>";
if(sizeof($array)>1)
{
echo "Left side length : ".intval(strlen($array[1]));// $array[1] contains left hand check the string length side
}
?>

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))

Convert a string containing a number in scientific notation to a double in PHP

I need help converting a string that contains a number in scientific notation to a double.
Example strings:
"1.8281e-009"
"2.3562e-007"
"0.911348"
I was thinking about just breaking the number into the number on the left and the exponent and than just do the math to generate the number; but is there a better/standard way to do this?
PHP is typeless dynamically typed, meaning it has to parse values to determine their types (recent versions of PHP have type declarations).
In your case, you may simply perform a numerical operation to force PHP to consider the values as numbers (and it understands the scientific notation x.yE-z).
Try for instance
foreach (array("1.8281e-009","2.3562e-007","0.911348") as $a)
{
echo "String $a: Number: " . ($a + 1) . "\n";
}
just adding 1 (you could also subtract zero) will make the strings become numbers, with the right amount of decimals.
Result:
String 1.8281e-009: Number: 1.0000000018281
String 2.3562e-007: Number: 1.00000023562
String 0.911348: Number: 1.911348
You might also cast the result using (float)
$real = (float) "3.141592e-007";
$f = (float) "1.8281e-009";
var_dump($f); // float(1.8281E-9)
Following line of code can help you to display bigint value,
$token= sprintf("%.0f",$scienticNotationNum );
refer with this link.
$float = sprintf('%f', $scientific_notation);
$integer = sprintf('%d', $scientific_notation);
if ($float == $integer)
{
// this is a whole number, so remove all decimals
$output = $integer;
}
else
{
// remove trailing zeroes from the decimal portion
$output = rtrim($float,'0');
$output = rtrim($output,'.');
}
I found a post that used number_format to convert the value from a float scientific notation number to a non-scientific notation number:
Example from the post:
$big_integer = 1202400000;
$formatted_int = number_format($big_integer, 0, '.', '');
echo $formatted_int; //outputs 1202400000 as expected
Use number_format() and rtrim() functions together. Eg
//eg $sciNotation = 2.3649E-8
$number = number_format($sciNotation, 10); //Use $dec_point large enough
echo rtrim($number, '0'); //Remove trailing zeros
I created a function, with more functions (pun not intended)
function decimalNotation($num){
$parts = explode('E', $num);
if(count($parts) != 2){
return $num;
}
$exp = abs(end($parts)) + 3;
$decimal = number_format($num, $exp);
$decimal = rtrim($decimal, '0');
return rtrim($decimal, '.');
}
function decimal_notation($float) {
$parts = explode('E', $float);
if(count($parts) === 2){
$exp = abs(end($parts)) + strlen($parts[0]);
$decimal = number_format($float, $exp);
return rtrim($decimal, '.0');
}
else{
return $float;
}
}
work with 0.000077240388
I tried the +1,-1,/1 solution but that was not sufficient without rounding the number afterwards using round($a,4) or similar

Categories