php variable magic. How php work with decimal and hex - php

$a1 = 010;
print (int)$a1;
print value = 8
Anybody can explain how php made this result?
Because 010 in hex = 16.

010 is 10 in base-8, i.e. 8 in base-10.
Full reference from the manual:
<?php
$a = 1234; // decimal number
$a = -123; // a negative number
$a = 0123; // octal number (equivalent to 83 decimal)
$a = 0x1A; // hexadecimal number (equivalent to 26 decimal)
$a = 0b11111111; // binary number (equivalent to 255 decimal)
?>

It's not hex. It's octal.
For HEX:
$a = 0x10;
For octal
$a = 010;
For HEX number, you have to start with 0x.

Related

PHP How to take first 2 bits from byte and make new byte

Operations on bits.
How to take 2 bits from byte like this:
take first 2 from 12345678 = 12;
Make new byte = 00000012
For example as asked in discussion by jspit :
$char = 'z'; //is 122, 0111 1010
$b = $char & '?'; // ? is 63, 0011 1111
echo $b; //$b becomes 58 and shows ':'
//if integer used you get:
$b = $char & 63;// 63 is 0011 1111 as '?' but $char is string and you get 0 result:
echo $b; //$b becomes 0 because conversion to integer is used from string and $char becomes 0 and get 0 & 63 = 0, and here is error.
For clearance operation is on bits not on bytes, but bits from bytes.
'string' >> 1 not work, but this is second problem.
Codes of char You can check on my site generating safe readable tokens, with byte template option on. Site is in all available languages.
I think I found good answer here:
how to bitwise shift a string in php?
PS. Sorry I cant vote yours fine answers but I have no points reputation here to do this ;)...
I hope you understand bits can only be 0 or 1, I'm assuming when you say "12345678" you're just using those decimal symbols to represent the positions of each bit. If that is the case, then you're looking for bitwise operators.
More specifically:
$new = $old >> 6;
This bitwise shift operation will shift all bits 6 positions to the right, discarding the 6 bits that were there before.
You can also use an or operation with a bitmask to ensure only 2 bits remain, in case the variable had more than 8 bits set:
$new = ($old >> 6) | 0b00000011;
function highestBitsOfByte(int $byte, int $count = 2):int {
if($count < 0 OR $count > 8) return false; //Error
return ($byte & 0xFF) >> (8-$count);
}
$input = 0b10011110;
$r = highestBitsOfByte($input,2);
echo sprintf('%08b',$r);
The integer number is limited to the lowest 8 bits with & 0xFF. Then the bits are shifted to the right according to the desired length.
example to try: https://3v4l.org/1lAvO
If there is a character as input and the fixed number of 2 bits is required, then this can be used:
$chr = 'z'; //0111 1010
$hBits = ord($chr) >> 6;
echo sprintf('%08b',$hBits); //00000001

Why PHP substr function returns wrong value?

Here is the example code:
<?php
$number = 0130;
$a1 = substr($number,0,1);
$a2 = substr($number,1,1);
$a3 = substr($number,2,1);
$a4 = substr($number,3,1);
$a = [$a1,$a2,$a3,$a4];
echo $a1;
I got result is 8 why not 0?
Because 0130 is an octal number literal (because of the 0 prefix), and it's actual value is decimal 88. (Just try echo $number; and see for yourself.)
Therefore substr('88', 0, 1); is 8.
0130 is an octal number which value is 88.
Put your number between quotes (even casting it as a string will cast 88):
$number = '0130';

Why is the answer 15 here?

For the following code snippet the answer is 15.
$a = '5 USD';
$b = 10;
echo $a + $b;
But in the variable $a, if 5 is in between 'USD' or after 'USD' the output is 10. Why is it so?
From php.net:
When a string is evaluated in a numeric context, the resulting value
and type are determined as follows.
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. In all other
cases it will be evaluated as a float.
The value is given by the initial portion of the string. If the string
starts with valid numeric data, this will be the value used.
Otherwise, the value will be 0 (zero). Valid numeric data is an
optional sign, followed by one or more digits (optionally containing a
decimal point), followed by an optional exponent. The exponent is an
'e' or 'E' followed by one or more digits.
Literally:
$a + $b means numeric + numeric.
"5 USD" starts with a valid numeric data, so PHP converts it into 5.
"USD 5" or "U5SD" starts with not valid numeric data, so PHP converts it into 0.
UPDv1:
<?php
header('Content-Type: text/plain');
function plus($a, $b){
echo $a, ' + ', $b, ' = ', $a + $b, PHP_EOL;
}
plus('5 frogs', 3); // 5 + 3 = 8
plus('frogs: 5', 3); // 0 + 3 = 3
plus('f5rogs', 3); // 0 (not HEX) + 3 = 3
plus('0xF5', 3); // 245 (HEX) + 3 = 248
plus('0011b', 3); // 11 (not BIN) + 3 = 14
plus('1E5', '1.2xx'); // 100000 (FLOAT) + 1.2 (FLOAT) = 100001.2
plus('true', 2); // 0 (not BOOL) + 2 = 2
?>
Also, check out this: php string number concatenation messed up.
UPDv2:
There is "no way" for PHP to typecast string value to octal, regardless of zero-fill effect. Still, as mentioned before, PHP able to typecast string to hexadecimal.
<?php
header('Content-Type: text/plain');
function plus($a, $b){
echo $a, ' + ', $b, ' = ', $a + $b, PHP_EOL;
}
plus(008, 12); // Invalid octal, PHP assumes it is 0. Result: 12.
plus('008', 12); // Invalid octal? No, it is decimal. Result: 20.
plus(0x0F, 1); // Valid hexadecimal. Result: 16.
plus('0x0F', 1); // Valid hexadecimal. Result: 16.
plus('0x0X', 1); // Invalid hexadecimal, PHP assumes it is 0. Result: 1.
?>
It is not mentioned in "string to number conversion" docs.
See PHP Manual Language.types.string.conversion
String conversion to numbers
When a string is evaluated in a numeric context, the resulting value and type are determined as follows.
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. In all other cases it will be evaluated as a float.
The value is given by the initial portion of the string. If the string starts with valid numeric data, this will be the value used. Otherwise, the value will be 0 (zero). Valid numeric data is an optional sign, followed by one or more digits (optionally containing a decimal point), followed by an optional exponent. The exponent is an 'e' or 'E' followed by one or more digits.
Examples can be found in the manual (link above)
$foo = 1 + "bob-1.3e3"; // $foo is integer (1)
$foo = 1 + "bob3"; // $foo is integer (1)
$foo = 1 + "10 Small Pigs"; // $foo is integer (11)
Answering your question
$a = '5 USD'; // The string starts with number, so by an implicit cast to int, it will be 5
$b = 10;
echo $a + $b; // = 15
In the other example you wrote
$a = 'USD 5'; // The string does not start with a number, so by an implicit cast to int, it will be 0
$b = 10;
echo $a + $b; // = 10
For more information on this conversion, see the Unix manual page for strtod(3).
Because
php > echo (int)"a";
0
So if you feed the PHP executable with
php > "USD 5" + "10"
it will cast both operands to integers:
php > (int)"USD 5" + (int)"10"
And thus you will receive result of 0 + 10.

related to php arithmetic

$y = 013;
echo $y + 5; //this result in 16
I can not figure it out how its ans is 16? Can any one help?
because 013 isn't decimal (base 10). it's octal (base 8). the value in decimal is:
(0 * 8^2) + (1 * 8^1) + (3 * 8^0) = 0 + 8 + 3 = 11
which gives the correct (though unexpected, at least by you) result of 16 when added to 5.
moral of the story: don't prepend a number literal with 0 unless you know what it means
number with leading zero is octal number
like
$a = 0123; // octal number (equivalent to 83 decimal
Integers can be specified in decimal
(base 10), hexadecimal (base 16), or
octal (base 8) notation, optionally
preceded by a sign (- or +).
To use octal notation, precede the
number with a 0 (zero). To use
hexadecimal notation precede the
number with 0x.
$y = 013;
echo $y + 5;
013 is octal number all php integer numbers are octal .
show this link. first.
http://www.ascii.cl/conversion.htm

Any Difference Between (int) 1 and 1 in PHP?

I was reading some code that a consultant provided us. It's a bit convoluted, and at the end of a function, it reads:
return (int) 1;
Instead of:
return 1;
PHP has a lot of magic in it; is this as bone-headed as it looks, or is there a valid reason to cast an integer as an integer?
No, it's the same. 1 is an integer literal.
See here these are all integer literals; casting to int has no effect:
$a = 1234; // decimal number
$a = -123; // a negative number
$a = 0123; // octal number (equivalent to 83 decimal)
$a = 0x1A; // hexadecimal number (equivalent to 26 decimal)
If you did return "1"; that would be an entirely different matter. There are some differences in behaviour between "1" (string) and 1 (int), namely with bitwise operators.
It's pretty bone headed. Integer literals are, well... integers.
1 === 1 however 1 !== '1'
also, when necessary, (as in this case it definitely isn't) I would suggest not typecasting with (int) use intval() instead.

Categories