Unexpected result in PHP bitwise operation - php

The operation 1539 | 0xfffff800 returns -509 in JavaScript and Python 2.7.
In PHP I get 4294966787.
Does anybody know why and could explain that to me. I would love to know how I get the expected result in PHP as well.

1539 | 0xfffff800 = 4294966787 (= 0xFFFFFE03)
This is perfectly right. So, PHP is right.
If you would like to have both positive and negative integers, you need some mechanism to determine whether the number is negative. This is usually done using the 2-complement of the number. You can negate a number by just inverting all the bits of the number and then add 1 to it. In order to avoid ambiguities, you cannot use all the bits of your integer variable. You cannot use the highest bit in this case. The highest bit is reserved as a sign bit. (If you would not do so, you never know if your number is a big positive number or a negative number.)
For exammple with an 8 bit integer variable, you would be able to represent numbers from 0 to 255. If you need signed values, you can represent number from -128 (1000 000 binary) to +127 (0111 1111).
In your example, you have a 32 bit number which has its highest bit set. In Python and JavaScript, it's interpreted as negative number, as they apparently have 32 bit variables, and there, the highest bit is set. They interpret that as negative number. So, the result of your calculation is also negative.
In the PHP version you are using, the integer variable seems to be 64 bit long and only the lower 32 bits are used. The highest bit (bit 63) is not set, so PHP interprets this number as positive. Depending on what you want to achive, you may want to fill up all bits from bit 32 to bit 63 with 1s which will create a negative number...

Related

Steps to work out the Not bitwise operator

I have read some previous questions in the past, but still, I could not work out the step I have to do
Bit not operation in PHP(or any other language probably)
What is “2's Complement”?
$a = -9;
echo ~$a; //print 8
If I understand correctly,the 1st step is to convert to binary. In binary, it is 1001. The NOT operator then convert from 1001 to 0110.
What do I have to do after this? Do I add a 1? I am lost in all the explanation given in the explanation.
Or is it simpler to make an educated guess (in the exam condition). If I take -9, (step 1) convert to 9 and (step 2) then take away 1. That would give me 8. Is this a correct pattern to work out the answer?
Well it's very easy but first you must note the fact that if you system is 32 bit you cannot use all 32 bits to represent the number rather just 31, same for 16 bit and 8 bit systems ; the rightmost bit is never used to denote the magnitude of the number but rather just the sign.
There are some areas where you can tell the system to use all the bits for magnitude so 2's complement isn't used as such and all numbers will be assumed positive but normally for the most "regular" business we use signed numbers
Here's an example for an 8-bit systems
Step 1. Covert it to binary (you did that already)
You can see since it's binary going right to left each place value is double of the next in contrast to decimal where each place value is 10 times of its predecessor
Step 2. Invert all the bits form the result from previous step
Step 3. Now add 1 to the accumulated result from the previous step
Now ~ to above result will give 00001000 ie 8
Why so?
Because you are using BITWISE operator it knows nothing of the underlying number it just does what it should - inverting rest of the things like how to make sense of this 1s0s is upto the system which does a reverse 2s complement but since it's a postive number (MSB is 0) so it knows there's no need to do anything it just converts it to decimal but had it been negative it would have done all the computation to reverse the 2s complement because 2s complement of positive number is same as that number.
Now note that if you are using signed number as in above you can use 8 bits to represent number from -128 to 127 so to represent 256 you must upgrade to 32 bit.
A fun thing is to note that in 2's complement form for positive numbers more 1s means greater magnitude whereas for negative numbers 0s mean more magnitude
It would be hard at first to interpret 2s complement directly so start first converting every 2's complement to binary then interpret it as decimal once you are proficient you can directly tell what a 2s complement form amounts to in decimal
Ref.
http://sandbox.mc.edu/~bennet/cs110/tc/tctod.html
https://www.rapidtables.com/convert/number/binary-to-decimal.html
http://onlinecalculators.brainmeasures.com/Numbers/TwosComplimentCalculations.aspx
https://www.quora.com/Why-computer-use-2s-complement-to-store-negative-number-instead-of-1s-complement
Update:
To answer your comment : above isn't applicable to positive numbers.2s complement of positive number is that same number itself you might ask why so? well it's because 2s complement was invented to mitigate the problem of subtraction so computers really don't have to implement a SUB circuit separately (in fact there isn't any SUB logic gate at all! all we have is AND OR and NOT that's why it's hard to implement a SUB circuit)
So now same circuit could be used for addition as well as subtraction which uses 2s complement 'hack' in to perform subtraction by doing addition!
So 1 is stored as 00000001 now when you NOT it ie ~00000001 gives11111110
now that -2 in 2s complement form

How to calculate 2^n in integer where n is in between 10 to 10000 in php?

I am working with some logical problems in my localhost. At a case I need to calculate power of 2 and sum them in integer type to proceed next case. I am using 32 bit system, so I can calculate up to 2^31, as well as sum up to 2147483648 in integer type.
How can I increase the number of power up to 10000? Is there any math library or class available to calculate big integer effectively?
Probably I dont need the power over thousand but I am curious if it is possible in PHP or not. Can anyone answer my with proper reference ?
There are two libraries available in PHP to work with BIG Numbers.
They are,
BC Math
GMP
In both of them GMP has more library function then BC Math.
GMP - It considers leading zeros in a number string as meaning the
number is in octal, whereas 'BC' doesn't. Reference:
http://www.php.net/manual/en/book.gmp.php

Why is var_dump((int)(PHP_INT_MAX + 1)) a negative number?

I pulled this result from here:
And interestingly, the result of var_dump((int)(PHP_INT_MAX + 1)) will be displayed as a negative number (in the case of this specific example, it will display int(-9223372036854775808)). Again, the key here is for the candidate to know that the value will be displayed as a negative number.
Is the int negative because adding 1 will overflow the integer bits and change the bit representing the sign of the int? What's the reason?
#kainaw is right.
This is called "buffer overflow". PHP handled it in the best way possible.
If PHP didn't make that integer positive, there would be an extra "bit" floating around in the RAM (probably causing a 502 error, but it could be much worse)

Cannot insert the value '-1' into database

I cannot insert the value "-1" into database, the table set the field is int(10).
I don't know what the problem is. Could you help me. thank you.
$sql2="INSERT INTO attendance_count(username,date,count_time,appendix)VALUES('$applicant','$date1','-1','$altext')";
mysql_query($sql2);
don't put single quote since its an int.
Make sure the column isn't UNSIGNED
the documentation is saying it won't store a literal "-" character,
which means it's probably now doing what the other signed INTEGER
fields have always done and it's storing a sign bit to denote negative
numbers instead.
You're still seeing a minus sign preceding the number because it's
being generated by MySQL as a result of that sign bit.
If you don't understand the sign bit, you can consider how a signed
byte can store numbers from -128 to 127, while an unsigned byte can
store numbers from 0 to 255. That's because one of the 8 bits in a
signed number is being used to store +/- (1 is negative, 0 is
positive), while the remaining bits offer numbers up to 2^7 (-128 or
127).
So, for example, if the bits 1111 had a sign bit they would equal -7
(negative+4+2+1), but if they were unsigned they'd equal 15 (8+4+2+1).
It's still the same amount of bits being stored.
You may wonder why the negative bound in a signed number can use the
8th bit, while the positive bound is limited to the sum of the 7 bits
(1 less than the 8th bit). This is because 10000000 is considered to
be both negative and the 8th bit simultaneously, because its
representation of -0 otherwise is redundant with 00000000 which
represents 0. There's no distinction between negative and positive
zero, so a negative most significant bit is always the value of that
bit itself (but negative).
the column where youre entering the value -1 should be SIGNED
INT(SIGNED) values can be a minimum of-2147483648 to a maximum of 2147483647
INT(UNSIGNED) values can be a minimum of 0 to a maximum of 4294967295

Using long int in PHP

I am trying this out, but am unable to store large value
$var = rand(100000000000000,999999999999999);
echo $var; // prints a 9 digit value(largest possible)
How to get a desired value ?
From the manual:
The size of an integer is platform-dependent, although a maximum value of about two billion is the usual value (that's 32 bits signed). 64-bit platforms usually have a maximum value of about 9E18. PHP does not support unsigned integers. Integer size can be determined using the constant PHP_INT_SIZE, and maximum value using the constant PHP_INT_MAX since PHP 4.4.0 and PHP 5.0.5.
...
If PHP encounters a number beyond the bounds of the integer type, it will be interpreted as a float instead. Also, an operation which results in a number beyond the bounds of the integer type will return a float instead.
BC Math and GMP are the (only?) way to manipulate this limitation.
PHP ints are typically 32 bits. Other packages provide higher-precision ints: http://php.net/manual/en/language.types.integer.php
If you need to work with very large numbers I have found success with BC Math. Here is a link to everything you need to know:
http://php.net/manual/en/book.bc.php
If you want to generate the number and manipulate as a native type, you can't with most PHP installations (either you have 32 or 64 bit ints and nothing else), as the other answers have already stated. However, if you are just generating a number and want to pass it around a possible trick is to just concatenate strings:
$var = rand(0,PHP_INT_MAX).str_pad(rand(0, 999999999), 9, 0, STR_PAD_LEFT);
echo $var;
On a platform in which PHP uses a 32 bit integer, this allows you to get a near random integer (as a string) that is bigger than 32 bits ( > 10 decimal places). Of course, there is a bias in this construction which means you won't cover all the numbers with the same probability. The limits of the rand() calls obey normal decimal rules so its simple to adjust the upper bound of the number you want.
If all you're doing is storing/transmitting/showing this value, the string will be just fine. Equality and greater/less than tests will also work. Just don't do any math with it.

Categories