Large numbers in PHP - php

I've been playing around with large numbers in PHP and was just wondering what module/process it uses to calculate the large numbers, and why it isn't used for all PHP numeric functions.
Hope this explains it a little better
My PHP_INT_MAX is 2147483647 (31 bits)
But, I figured out can create a 1017 bit number, by using:
$largenumber = pow(142,142);
This number is 310 digits long so I wont paste it in here ...
But then if I then try convert it to binary:
decbin($largenumber);
I get 1111111111111111111111111111111 (31 bits ... PHP_INT_MAX)
So, if the pow() function can handle this large number, why can't the decbin() function handle it?

From the official PHP documentation on pow:
base raised to the power of exp. If both arguments are non-negative
integers and the result can be represented as an integer, the result
will be returned with integer type, otherwise it will be returned as a
float.
$largenumber = pow(142,142);
var_dump($largenumber); //float(INF)
pow returns a float, which decbin tries to convert to an int and where you exceed the maximum integer value.

Related

Totally wrong result of intval and(int) of double number

I've got this problem on Windows 10 with both php 7 and 7.1 and also on raspbian with PHP 7.0.33
When I try to cast a large double (a miliseconds timestamp) to int I get a totally wrong result. Example:
$a = 1512298800000.0;
echo intval($a);
The output is: 470311808
Any suggestion on how to troubleshoot this?
Based on intval() Manual, it cleary states:
Return Values
The integer value of var on success, or 0 on failure. Empty arrays return 0, non-empty arrays return 1.
The maximum value depends on the system. 32 bit systems have a maximum signed integer range of -2147483648 to 2147483647. So for example on such a system, intval('1000000000000') will return 2147483647. The maximum signed integer value for 64 bit systems is 9223372036854775807.
Strings will most likely return 0 although this depends on the leftmost characters of the string. The common rules of integer casting apply.
And
Notes
Note:The base parameter has no effect unless the var parameter is a string.
So basically it seems you are using 32-bit system and value got overflowed from the range of integer.

Exceed PHP binary limit

I was trying to do some sort of XOR binary crypting algorithm in PHP and so I needed to convert large strings into binary. The problem is that PHP seems to be very limited in terms of binary calculation / storage as a string of six letters only, once converted, exceeds the PHP INT limit.
That means unpacking a big string to binary just gives a unusable number. I tried to do the string unpacking by splitting the string into packs of 4 letters and then unpacking them, but then I've got troubles with the repacking where it gives random characters instead of the original ones.
How can I do the unpacking of very long strings, and then store them either in a string (made only of 0s and 1s) or in a big array (where each value is either a 0 or 1, the key indicating the location of this bit) ?
have you tried the GMP library? Man page GMP
quick test code:
<?php
$gmpValue1 = gmp_init("1562767628166296698262", 10); // note: using base 10 (decimal)
$gmpValue2 = gmp_init("2163623626362663286446", 10);
$gmpValue3 = gmp_xor($gmpValue1, $gmpValue2);
echo gmp_strval($gmpValue3, 10) . "\n"; // note: using base 10 (decimal)

String number to integer not working PHP

I am trying to get a string number to an integer but it's not working as expected here is the code with the problem:
$usage['msisdn'] = "46720000000";
$usage['msisdn'] = (int)$usage['msisdn'];
echo $usage['msisdn'];
It echoes 2147483647 as integer but I want to get 46720000000 as integer.
What's wrong?
By the way I'm parsing the data using json_encode();
UPDATE: Nevermind I've got it to work with intval()
That's because the maximum value of int32 is 2,147,483,647. Your phone number exceeds this value.
You can find the maximum value of int on your server using:
echo PHP_INT_MAX;
I think that storing a phone number as integer is a bad practice and it may affect you later. Why? Because the phone number may start with:
IDD: 00 or +
NDD: 0
Also, you may want to format the phone number at some point, storing it as string making this part much easier.
Christmas bonus :) libphonenumber-for-php
Your code isn't working because the conversion string to int as a maximum value based on your system as quoted in the documentation :
The maximum value depends on the system. 32 bit systems have a maximum signed integer range of -2147483648 to 2147483647. So for example on such a system, intval('1000000000000') will return 2147483647. The maximum signed integer value for 64 bit systems is 9223372036854775807.
Source : http://php.net/manual/en/function.intval.php
Since you cannot modify the max_int value easily, you could try to use a conversion to float instead.
$usage['msisdn'] = floatval($usage['msisdn']);

JavaScript VS PHP: The same calculation returns different result

I'm trying to do some simple math (?) in JavaScript:
( 1023 * 2 ) + 76561197960265728;
I already did the same calculation in PHP, but the results are different:
JavaScript: 76561197960267780
PHP: 76561197960267774 (the right result)
I then tried the following:
http://jsfiddle.net/YxBa4/
Is there a "limit" in JavaScript for high numbers in calculations?
//edit:
Thanks for your answers, I now use the BigNumber one.
My full working code now:
on JSFiddle
In Javascript, numbers are 64 bit floating point values. The largest integer (magnitude) is 253, or Math.pow(2,53), or 9007199254740992. taken from: http://notepad2.blogspot.ca/2012/04/maximum-integer-in-javascript.html
You are 1351079458714420 over the limit.
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. taken from http://php.net/manual/en/language.types.integer.php
So basically PHP allows you more capacity for Integer values according to the PHP configuration.
The value 76561197960265730 id greater than the maximum allowed number size in javascript. Note that there are no real integers in Javascript just the Number type which is always a 64bit floating point value and platform independent. But the largest possible integer value is just 2^53 because 11 bits are at least reserved for the numbers after the comma and the signage bit.
In your example you can see this by simply doing:
alert(76561197960265728);
What will give you already an error, even without any calculations. (output: '76561197960265730')
In php the maximum integer value depends on your system. If you are on a 64 bit system, the MAX integer value is 2^64 what is greater than (2 * 1023) + 76561197960265728. That'swhy the calculation succeeded in PHP - on a 64 bit system
In PHP you can detect the maximum integer size on your system by reading the constant PHP_INT_MAX and `
You could use the bcmath extension for PHP and the JS conversion of it to get consistant results across the 2 languages:
bcadd('76561197960267774', '76561197960267774');
// 153122395920535548
http://jsfiddle.net/zELmm/
http://phpjs.org/functions/bcadd/
http://php.net/manual/en/function.bcadd.php
Update:-
BigInt was added as a native features of JavaScript.
But still there are some precision error on round off, A workaround Comparison
For example here full code for comparing BigInt with Number in JavaScript
As per Initial Problem Here :-
PHP: 76561197960267774 (the right result)
var num = BigInt( 1023 * 2 ) + 76561197960265728n;
console.log(num.toString());
/*
num.toString() removes n at the end of digit.
Output: 76561197960267774
*/
Where bigint, created by appending n to the end of an integer literal or by calling the BigInt() constructor.
So after using BigInt:-
JavaScript: 76561197960267774 (the right result)

Why does PHP transform 15+ digit long integer on output [duplicate]

This question already has answers here:
round in PHP shows scientific notation instead of full number
(3 answers)
Closed 9 years ago.
Why does echo 100000000000000; output 1.0E+14 and not 100000000000000?
This kind of transformation of integers on output happens only for integers that are 15 digits long and longer.
PHP will convert an integer to float if it is bigger than PHP_INT_MAX. For 32-bit systems this is 2147483647.
The answer to the questions is related to the string representation of floats in PHP.
If the exponent in the scientific notation is bigger than 13 or smaller than -4, PHP will use scientific representation when printing floats.
Examples:
echo 0.0001; // 0.0001;
echo 0.00001; // 1.0E-5
// 14 digits
echo 10000000000000; // 10000000000000
// 15 digits
echo 100000000000000; // 1.0E+14
See float vs. double precision
That number is too big to fit into a 32 bit integer so PHP is storing it in a float.
See the integer overflow section in the php manual.
On the off chance that you need really big integers, look into GMP.
PHP cannot handle integers that big, and therefore treats them as floats. Floats are typically represented in scientific notation to take into account the inaccuracies past a certain number of significant digits.
The number is too big to be stored as integer by PHP on your platform,
so it is stored as a floating-point number.
The rules of conversion to string are different for float-numbers and integers.
Try the following:
var_dump(100000000000000);
echo(is_int(100000000000000) ? 'an integer' : 'not an integer');
Output:
float(1.0E+14)
not an integer
Any number larger than PHP's built-in integer size is stored and represented as a float.
To format a number in a particular way on output, use a function such as printf .

Categories