How to flip bits without leading signs in PHP? - php

On flipping/inverting bits in PHP using the ~-operator the output contains a lot of leading signs, which are obviously unnecessary, if you output the raw integer. On parsing the binary-value back to an integer, you will see that the values are not equal. See the example attached below.
$integer = 0b11110; // raw integer
echo "{$integer}: " . decbin($integer) . PHP_EOL; // print integer-value before flipping
$integer = ~$integer; // flipping/inverting the integer
$binary = decbin($integer);
echo "{$integer}: " . $binary . PHP_EOL; // print integer-value after flipping
echo bindec($binary) . PHP_EOL; // print parsed binary-value
see result on 3v4l.org
Is it possible to remove the leading signs, so that the second usage of echo will output something like 100001 (or just 00001, if you don't take the plus/minus sign into account), because -31 is obviously not the same as 1111111111111111111111111111111111111111111111111111111111100001.

Related

Properly remove leading zeroes with decimals like 0.1

I aim to remove leading zeros like this:
echo ltrim(000.1, '0'); // .1 (should end up as 0.1)
echo ltrim(0, '0'); // empty (should end up as 0)
echo ltrim(00005.5, '0'); // 5.5 (correct)
Using ltrim() works fine with values like 00005.5 but doesn't work with 0.1 as 0 (as you would expect by the logic).
My question is, how can I remove leading zeros in values like 0.5 and avoid trimming value if it is 0?
Just multiply it with 1 and php will cast it to float.
echo "000.1"*1 . "\n"; //0.1
echo "0"*1 . "\n"; //0
echo "00005.5"*1 . "\n";//5.5
https://3v4l.org/mnN56
Or float cast it
echo (float)"000.1" . "\n";
echo (float)"0" . "\n";
echo (float)"00005.5" . "\n";

Arithmetic in the return statement cause unexpected behavior

I'm currently learning PHP from a HTML, CSS, and JS background and I came across some unexpected behavior that interested me. Consequently, I experimented with the following code.
Experiment 1:
It seems that when written the return statement is written like this, everything before the arithmetic is removed/not rendered.
Code:
<?php
function add($num, $num2) {
return $num."+".$num2." = ".$num + $num2."<br>";
}
echo add(10, 7) . add(20, 1);
?>
Outputs:
17<br>
21<br>
Experiment 2:
However, when I change the first variable/parameter from $num to $num2, it seems that every between the first variable and the + operator is removed.
Code:
<?php
function add($num, $num2) {
return $num2."+".$num2." = ".$num + $num2."<br>";
}
echo add(10, 7) . add(20, 1);
?>
Outputs:
14<br>
2<br>
Experiment 3:
After trying it in JS, I realized that putting brackets around the arithmetic equation would output the expected result.
Code:
<?php
function add($num, $num2) {
return $num."+".$num2." = ".($num + $num2)."<br>";
}
echo add(10, 7) . add(20, 1);
?>
Outputs:
10+7 = 17<br>
20+1 = 21<br>
(Also making a $sum variable would fix the problem)
Question:
My question is what causes the unexpected behavior by not putting the brackets around the equation?
The behavior you are seeing is the result of "type juggling".
Because PHP is not strictly-typed, a string can be interpreted as an integer when needed (or assumed to be needed by the interpreter), or vice versa. So the data type is converted, and if you're not careful can cause issues. In many other languages you would get an error if you treated a string like an integer or an integer like a string. JavaScript, for example, has String.parseInt() to explicitly change the type.
What the interpreter is doing is roughly the following, step-by-step:
$num - establish an integer with value 10
10."+" - concatenating an integer with a string
Convert the current output to a string (10 becomes "10"), and append a plus sign
Output is now "10+"
"10+".$num2 - concatenating a string with an integer
Convert the integer to a string and append it
Output is now "10+7"
"10+7"." = " - concatenating 2 strings
Output is now "10+7 = "
"10+7 = ".$num - concatenating a string with an integer
Convert the integer to a string and append it
Output is now "10+7 = 10
"10+7 = 10" + $num2 - arithmetic calculation between a string and an integer
Convert the string to an integer and add it to the next integer.
In this case, when PHP converts a string to an integer, it starts at the beginning of the string and returns all numerals until it hits the first non-number, so "10+7 = 10" pulls out the 10, then hits the + and stops looking for numbers.
Output is now 17;
17."<br>" - concatenation of an integer and a string
Convert the integer to a string and append the <br>
Output is now 17<br>.
For reference:
Documentation on type juggling: http://php.net/manual/en/language.types.type-juggling.php
How does PHP know that you don't want to take this $num."+".$num2." = ".$num and arithmetically add it to this $num2."<br>"? It doesn't, unless you use parentheses to cause the $num + $num2 to happen first.
In the first example:
$num."+".$num2." = ".$num
Equates to the string: 10+7=10, and then:
$num2
Equates to 7.
When you attempt to add them + the string 10+7=10 must be cast to an integer 10 and and when added to 7 gives you 17 then the string <br> is concatenated.
See PHP: String Conversion to Numbers
With parentheses:
$num."+".$num2." = ".($num + $num2)."<br>";
You get string 10+7= concatenated with 10+7 (17) concatenated with string <br>.

Display full 1-128 bit decimal to binary using PHP

I know this seams to be easy but, I have a question to this particular situation.
I already know how to convert decimal to binary using PHP, but I want to display
the full bit sequence, but surprisingly, I don't know how.
the conversion must be like this:
converting 127(decimal) to binary using PHP = 1111111. the bit sequence is 1-128 for every
octet(IP Address) so this must output = 01111111 even 128 is not used.
2nd Example:
1(decimal) to binary = 01. Want to display the full 1-128 binary sequence even if
128,64,32,16,8,4,2 is not used it must be like this 00000001 not 01.
this is my PHP code:
<?php
$octet1 = $_POST["oct1"];
$octet2 = $_POST["oct2"];
$octet3 = $_POST["oct3"];
$octet4 = $_POST["oct4"];
echo decbin($octet1) ," ", decbin($octet2) ," ", decbin($octet3) ," ", decbin($octet4);
?>
this only displays the shortened binary just like this:
16 to binary is 10000 or but i want to display this 00010000(Full length)
How can I do that?
How about using sprintf with b format specifier:
echo sprintf("%08b", 127);
// 01111111
echo sprintf("%08b.%08b.%08b.%08b", 127, 0, 0, 1);
// 01111111.00000000.00000000.00000001
You need to pad it:
echo str_pad($str, 8, '0', STR_PAD_LEFT);

from 1.297503E+17 to 129750300000000000

How can I get php to not use 1.297503E+17 on large int but 129750300000000000
code:
$dag = 29;
$maand = 03;
$jaar = 2012;
$expdate = $dag . "-" . $maand . "-" . $jaar;
$unixstamp = strtotime($expdate);
echo $unixstamp."<br />";
$winstamp = ($unixstamp + 11644560000) * 10000000;
I'm trying to use the number for a Timestamp in ldap.
That's what I would do (tested on 32b platform)
>> number_format(1.297503E+17,0,'.','')
'129750300000000000'
just be aware, that what you get back is a string, an will be converted back to float if you try doing any arithemtics on it. If you need to do math on large integers look into bc_math extension
PHP internally uses big enough integers. Your problem here is the use of echo:
printf ("%d", $winstamp);
$winstamp++;
printf ("%d", $winstamp);
output:
129775320000000000
129775320000000001
Hope this helps
echo rtrim(sprintf("%0.15f", $winstamp), "0.");
This uses sprintf to print a maximum of 15 decimal places, and then trims off any trailing 0 or . chars. (Of course, there's no guarantee that everything will be rounded nicely with trailing zeros as you might expect.)
If you just want a fixed size, then you can adjust the 15 and remove the rtrim.
Apparently, when PHP encounters a number that exceeds the upper limit of 2,147,483,647 for an integer, it automatically converts the number’s type from integer into a double.
Fortunately, we can format these numbers in scientific notation back to their standard integer form using the number_format() function. Here is how to do it:
$winstamp = 1202400000;
$formatted_stamp = number_format($winstamp , 0, '.', '');
echo $formatted_stamp; //outputs 1202400000 as expected

PHP: on 32 bit system INT_MAX displays wrong?

I was simply wishing to test for overflow on an integer, such as in C (well, if it were just over integer max anyway). When I looked to see if PHP was actually doing what I told it to, it seems it fails for some reason. Here are my tests of the problem:
define('INT_MAX', 0x7FFFFFFF);
print "In decimal: " . hexdec(INT_MAX) . "<br/>";
print "In decimal: " . hexdec(0x7FFFFFFE) . "<br/>"; //Under int_max
print "In hex: " . dechex(hexdec(INT_MAX)) . "<br/>";
print "Float: " . ((bool)is_float(INT_MAX)?'true':'false') . "<br/>";
Results being:
In decimal: 142929835591
In decimal: 142929835590
In hex: 47483647
Float: false
As I saw on the manual, it will cast to float if overthrown, but it seems to not and is clearly way higher. Am I being insane and missing something here, or is there some odd problem I should really need to know about when working with hexidecimal in PHP?
Your program makes no sense, because you are taking 0x7FFFFFFF which is 2147483647, and then treating it like 0x2147483647, which is 142929835591 in decimal.
Anyway, PHP already has a constant that you can use:
var_dump(PHP_INT_MAX + 1); // converted to float
define('INT_MAX', 0x7FFFFFFF);
This defines INT_MAX to be integer 2147483647. It is unnecessary to interpret it as a hexadecimal number. If you really want to use INT_MAX as a literal hexadecimal value, then you need to declare it as '7FFFFFFF' (inside a string); then the hexdec function will interpret the hexadecimal notation and convert it to a decimal value.
print(dechex(INT_MAX) . "\n");
This prints "7fffffff".

Categories