INT max size for 32bit system - php

Lets assume we are talking about 32bit system.
PHP doesn't support unsigned INT. It means that INT value should be between -2,147,483,648 and 2,147,483,647 values. And INT takes 4 bytes to store a value which are 32 bits length.
So does it mean that I have only 31 bits for value and 1 bit for sign? Or I can use whole 32 bits to store a value?

You are using the whole 32 bits. It's just that the default output functions interpret it as signed integer. If you want to display the value "raw" use:
printf("%u", -1); // %u for unsigned
Since PHP handles the integers signed internally however, you can only use bit arithmetics, but not addition/multiplication etc. with them - if you expect them to behave like unsigned ints.

2147483647 is the usual value 2^31-1. 1 bit for sign and -1 because we also represent 0.
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."

As far as i know on a 32-bit system the largest positive integer possible is 2147483647 values above will be float values, since a float value in php can take values up to 10000000000000.

First of all, if you want to do calculations with huge numbers (say, regulary greater than 10k), you should use the bcmath arbitrary precision module.
Secondly, the official php implementation uses the Two's complement internally to represent numbers, like virtually all other compilers and interpreters. Since the entropy of the signed bit (if you count 0 as positive[1]) is 1, and the entropy of 31 bits is, well, 31, you can store 232 = 4 294 967 296 distinct values. How you interpret them is up to your application.
[1] - 0 is neither positive nor negative.

Normally with 32 bit integers the difference between signed and unsigned is just how you interpret the value. For example, (-1)+1 would be 1 for both signed and unsigned, for signed it's obvious and for unsigned it's of course only true if you just chop the overflow off. So you do have 32 bits to store values, it just happens to be so that there's 1 bit that is interpreted differently from the rest.

Two's complement is most frequently used to store numbers, which means that 1 bit is not wasted just for the sign.
http://en.wikipedia.org/wiki/Two's_complement
In PHP if a number overflows the INT_MAX for a platform, it converts it to a floating point value.

Yes if it would have used unsigned integer it will use 32 bit to store it as you don't need sign in that case but as it supports only signed integers a 32 bit systems will have 31 bit for value and 1 bit for sign s0 maximum signed integer range is -2147483648 to 2147483647.

Related

Unexpected result in PHP bitwise operation

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

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

Why are large array indices not stored properly?

I am dealing with data that involves very large primary keys (12 digits). When I try to put the data in an array in the form id => value, the index is not assigned properly.
$test = array(190337172011 => 'Apple');
print_r($test);
Result:
Array ( [1358610987] => Apple )
Sometimes it even results in a negative number. Why does this happen? Is it a bug?
I am running PHP 5.3.10 on IIS.
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.
source: http://php.net/manual/en/language.types.integer.php
You are using a 32 bit PHP version on probably a 32 bit windows operating system, for example Windows XP.
For numerical array indexes PHP uses the integer variable type to store the keys. Those are limited. This limitation becomes visible if you choose a value greater than the limit which will either trigger a max or a turn-around depending on the PHP version and the operating system.
The value 190337172011 is too large of the integer type on your system, that's why you get a cap through roundtrip with a result of 1358610987. Roundtrip means, that after the possible maximum positive number, the next number is the lowest possible number, which is the "largest" negative number that can be expressed. That's why you get negative numbers as well.
You can work around that by storing the values as string keys which needs some pre-fixing:
$test = array('ID' . 190337172011 => 'Apple');
print_r($test);
This is normally enough to make your code more portable. You can choose any string prefix as you like, ID is just exemplary, but you need at least one non-numeric character.

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.

Generating a natural number ouf of PHP's lcg_value()?

I want to produce a natural number (a positive integer between 0 and x) by using lcg_value(). This is what I can see from the actual source code for the function:
/*
* combinedLCG() returns a pseudo random number in the range of (0, 1).
* The function combines two CGs with periods of
* 2^31 - 85 and 2^31 - 249. The period of this function
* is equal to the product of both primes.
*/
Now, how would I turn that float into a natural number so that I do not lose information/entropy. Currently I just do it like this:
$number = pow(2,31) * lcg_value();
However, I have a feeling in my gut that it's not perfect. How about 2^62? Or perhaps 2^31-334? Or 2^62-334? I don't know.
either type float or int are bounded by platform
Integer 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.
float The size of a float is platform-dependent, although a maximum of ~1.8e308 with a precision of roughly 14 decimal digits is a common value (the 64 bit IEEE format).
to maintain highest precision of float, u can refer http://www.php.net/manual/en/function.bcmul.php

Categories