Numeric String (arbitrary size) -> Multiple Integers - php

I'm running into a problem because my database has BIGINT data (64-bit integers) but the version of PHP I'm running is only 32-bit.
So when I pull out value from a table I end up with a numeric string representing a 64-bit integer in base 10. What I would ideally like to do is use the 64-bit integer as a bitmask. So I need to go to either two 32-bit integers (one representing the upper part and one the lower part) or a numeric string in base 2.
Problem is I can't just multiply it out because my PHP is only 32-bit. Am I stuck?

You can use MySQL's bit shift operators to split the 64-bit integer into two 32-bit integers. So, you could select:
select (myBigIntField & 0xffffffff) as lowerHalf,
(myBigIntField >> 32) as upperHalf

To handle arbitrary size integers, you have two options in PHP: GMP and BC Math methods.
I believe GMP is more efficient by using some custom resources, while BC uses strings directly.
If you won't be processing too many (thousands or more) of numbers at a time, you may use BC directly.

You have a few options here:
Use either BCMath or GMP if they are included in your PHP installation. Both should provide arbitrary-length integers.
Ask the database to convert the integer to a 64-character long bit string instead
Write a bignum implementation yourself (more work :-))

Related

Bitwise operator with large numbers

Is there a way to check greater values then "2147483648"?
I have to work with numbers up to "6.73297395398192e212" (2^707).
The data is stored in a mysql-database as float.
Maybe I'm just using the wrong search terms or there is not a good way.
A double precision value uses 8 bytes, and you obviously cannot store 707 bits in those (which I assume you are trying to do). It can store a value of 1e308 by an approximation that costs precision in the lower digits, which makes it a bad choice for storing data that you want to do bitwise operations on. For bitwise operation on 8 bytes, you can use bigint.
Since MySQL 8, MySQL supports bitwise operations on binary string of arbitrary length, so you should store your value that way - a bit array is basically a binary string anyway. You cannot treat them as numbers though (e.g. add or multiply them like integers).
For earlier MySQL versions, bit operations on binary strings were limited to 8 bytes. You should still store your bits as a binary string (which allows for an easy upgrade), and write a small function that does the operation e.g. bytewise.

How to work with money values in PHP and MySQL?

Now I store balance field in MySQL like decimial(15, 2). And in PHP I use the bcmath library for operations:
bccomp($currentBalance, 100.15, 2) - for check if user have enough money.
bcadd($currentBalance, 100) - for increase user balance.
And etc.
This is working correctly, but BCMath doc says:
Passing values of type float to a BCMath function which expects a
string as operand may not have the desired effect due to the way PHP
converts float values to string, namely that the string may be in
exponential notation (what is not supported by BCMath), and that the
decimal separator is locale dependend (while BCMath always expects a
decimal point).
So I want to avoid surprises. What is the right way to deal with money?
As integers. Convert 100.15 to 10015 and keep track of the currency so you know how many decimal places to apply when displaying.
Follow http://php.net/manual/en/function.bcadd.php and http://php.net/manual/en/function.bccomp.php
I think you should pass params as string. In your case, maybe bccomp("$currentBalance", "100.15", 2) -> Not yet test.

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

What are the maximum size for a seed in php?

What is the maximum input value for a seed in PHP? Is it 2^32? 2^64? No limit?
I cannot seem to find an answer in PHP documentation.
php_srand takes a long, and it calls one of srandom, srand48, or srand (depending upon compilation defines).
It casts the seed value to an int in the case of srandom/srand, but passes the full long-typed value through to srand48 - so then it comes down to implementation of the system/stdlib random functions (and actual size of int).
Also, considering that mt_srand takes a uint32, I'd say it's reliable to expect 32-bit seeds to be considered distinct (even if they start the same sequence). A 64-bit seed is the upper value limit (even if the entire seed is not used), but is only realizable in a 64-bit version of PHP.
Any non-integer value (i.e. float) supplied as a seed will be coerced to an integer. The actual php_srand C function is only called after coercing the supplied PHP value to a long in the wrapper.
You can use getrandmax() to determine the maximum value. ref: http://www.php.net/manual/en/function.getrandmax.php
srand takes an int which I assume is a 32-bit number on 32-bit machines according to the docs. and 64 on 64-bit machines.

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