How to parse a String to a long with no loss - php

I'm having an issue when parsing a string to a long. I want the variable "695690829980893234" to be parsed to a long without any loss. I've looked around for a bit but nothing really seemed to have helped.
When using (double) $var it shows as a 4.2904753172133E+17 (which is not the way I need it)
Does anyone have any ideas? Much appreciated!

In standard PHP, the type long does not exist.
So, if you want to have a long integer, you may use the standard int type, or use an extension, such as BC or GMP.
Specifically, the value 695690829980893234 is in the integer range of 64bit PHP, but out of the integer range of 32bit PHP.
To convert to int:
First, please make sure the number is in the int range. Then just convert
$res = intval("695690829980893234");
if($res<PHP_INT_MAX){
// OK! inside the positive limitation
}
To convert to GMP
A GMP object represents an arbitrary length integer:
$res = gmp_init("695690829980893234");
Then, use GMP functions to operate the number, such as:
$res = gmp_add($res, gmp_init("100"));
$res = gmp_sub($res, gmp_init("200"));
and finally, convert it back to int or string:
$int = gmp_intval($res);
$str = gmp_strval($res);
Hope this answer helps.

Be sure you're running 64-bit version of PHP.
echo PHP_INT_SIZE;
8
Then it will cast string to int easily
$a = "695690829980893234";
$b = (int)$a;
var_dump($a, $b);
string(18) "695690829980893234"
int(695690829980893234)

Related

How to convert WEI to ETHER php

I need to convert string like 0x2fe84e3113d7b to the float type. This string comes from infura.io API as balance of the account. I've tried to use https://github.com/mbezhanov/ethereum-converter, but it makes no sense in this case (it always returns 0.00000 in any way). How to convert this string to 0.000842796652117371 with php?
use Bezhanov\Ethereum\Converter;
...
$this->converter = new Converter();
$weiValue = '0x1e1e83d93bb6ebb88bbaf';
dump($this->converter->fromWei($weiValue)); // returns 0.00000000000000000000000000000000000
$hexValue = hexdec($weiValue); // returns 2.2757423599815E+24
dump($this->converter->fromWei($hexValue)); // returns the same
I guess it caused by too long value on $hexValue (I mean converter can't convert long integers as it). But how to get the ether value from this hex?
https://www.investopedia.com/terms/w/wei.asp
1 Ether = 1,000,000,000,000,000,000 Wei (10^18)
and since this is currency, storing it as a floating point would be asinine, so it's got to be a 64-bit integer there.
Deleted my overwrought answer for a simple:
var_dump(
$wei = hexdec("0x2fe84e3113d7b"),
$wei / pow(10, 18)
);
Output:
int(842796652117371)
float(0.000842796652117370993)
Which, coincidentally, also illustrates why you don't want to use floats for currency. Also, WFM.
Still doesn't explain why you have:
$hexValue = hexdec($weiValue); // returns 2.2757423599815E+24
Quoted in your example as that's several orders of magnitude wrong for the supposed input.

Why does this happen in php when we multiple string by number it always gives zero(0)?

Suppose we have a string $str = "a"; and number $num = 2;
$str = 'a';
$num = 2;
echo $str*$num;
Output:
0
When performing arithmetic operations on a string operand, PHP will try to convert the string to a number.
It does this by looking for digits at the beginning of the string and will try to convert them into a value. If there are no digits, the value will be zero.
(There's an edge case for strings containing e or E (scientific notation), but that's not relevant here.)
Good Question.
Same i did ask to my teacher when i was in collage,
The answer is.
String * int= infinity; //According to scientific calculator answer is infinity.
but we need to continue our so program it provide 0.
it is made by code by default answer.
Simply said the string will be converted to an integer with a value of 0. This will include most of the cases when only alphabetic values are used. If you try to add a integer value at the beginning of the string it would in theory become a integer of that value.
I would recommend to read Why PHP Strings Equal Zero or Comparison Operators
Maybe you are looking for str_repeat, instead doing looping for that, its a default value that php serve to you, or you need to cast A into integer . When you try to do calculation for data that is not in Integer/float data type. Usually PHP auto-typecast the variables. In some cases it wont. Then we have to type cast it manually

PHP: Does BCMath accept integers?

Is it safe to use INT-type variables in BCMath functions in PHP ?
Example:
<?php
$a = 1;
$b = "1";
echo bcadd($a,$b,0);
?>
This seems to work but is it safe to do this ? Or is there for example a risk that PHP can interpret an INT as something else than it's int value (I'm thinking about hexadecimal values etc) ?
Thanks !
Be careful with very large numbers. If you assign a literal integer > PHP_INT_MAX to a variable, PHP will automatically convert it to a float. I know you specifically asked about ints, and in that case you'd be passing a float, but if you don't know that about the automatic conversion it looks like you're using a large int, so I thought it worth mentioning.
$a = 9223372036854775808;
$b = '1';
var_dump($b); // float 9.2233720368548E+18
echo bcadd($a, $b, 0); // echoes 1
Basically, the function does take a string. If you give it something that isn't a string, PHP will automatically convert it to a string if it can, unless you have enabled strict mode.

Converting two integers into a long in PHP

I've got two integers and I need to convert them into a long. I'm totally lost on how to do this. The two integers that I need to convert are:
INT 1: 60850985
INT 2: 59150141
I need a method that converts two integers into a long. If you can post one, that'd be great.
When I say converting to a long, I'm wondering how you would do the equivalent of (long) from java in PHP
Let me be completely clear here:
I'm receiving two ints from the client, then I need to convert them to a long, then the single long is to be used again as a single int.
In essence, I need to take two ints and convert them into a single int. An example of how this is done in java would be:
long $intA = (long) readInt();
long $intB = (long) readInt();
return ($intA << 32) + $intB;
PHP stores numbers as integers or floats, where the size of the integer is platform dependent (but usally 32 bit, signed). If you need to represent a larger number you should use the BC Math functions.
Using BCM adding two numbers is like:
$a = '60850985';
$b = '59150141';
echo bcadd($a, $b);
or multiplying:
$a = '60850985';
$b = '59150141';
echo bcmul($a, $b);
EDIT:
If you want to get, how it should look as a 64-bit signed integer in 1-complement (if there is an overflow), then you have to do some manual conversion to cast the value inside the -2^63 .. 2^63-1 range:
For nonnegative values you can for example first cast it to 0 .. 2^64-1:
$long = bcmod($value, bcpow('2','64'));
Then if it's larger than 2^63-1 then subtract 2^63 from it, and then subtract this value from -2^63.
For negative values, first add 2^64, until the value is positive, then do the above steps.
But the above steps are only needed if you want to check how the string number looks if there was an overflow. Usually you don't need this, and probably you don't even need to use BCM as your numbers will easily fit inside PHP's signed 32-bit integer datatype (for which no casting is needed, conversion is automatical):
$a = '123'; // $a is a string
echo $a + 1; // will write 124, $a gets converted into int
You can force conversion if you want though:
$a = $a+0;
or
$a = (int)$a;
EDIT 2:
You can still use BCM functions to do the math:
$long = bcadd($low, bcmul($high, bcpow('2','32')))
// this essentially means:
// $long = $low + $high * 2^32
// which is
// $long = $low + $high << 32
Then, if the result is larger than 2^63-1 you can do some additional BCM calculations, described above to convert the unsigned integer into a signed one.
I used regular addition:
$int1 = 60850985;
$int2 = 59150141;
$result = $int1 + $int2;//120001126
Here's a quote from the PHP 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 you want to deal with large numbers use GMP ( http://www.php.net/manual/en/book.gmp.php ) or BCMath ( http://www.php.net/manual/en/book.bc.php ).
To elaborate on what AgentConundrum said, there isn't a need to cast an integer to a long in PHP. PHP is a dynamic language which means that generally, for operations on fundamental types, there is no need for casting (unless it is for some explicit purpose - i.e. a float to an integer), as PHP handles it for you.

PHP 64 bit numbers?

I have a simple function that I'm using but for some reason the number doesn't calculate correctly as it would in a calculator. I think it has something to do with the numbers being too large, or something to do with 64 bit. Is there any way I can convert them so that they would work correctly?
$sSteamComID = 76561197990369545;
$steamBase = 76561197960265728;
function convertToSteamID($sSteamComID) {
$sServer = bcmod($sSteamComID, '2') == '0' ? '0' : '1';
$sCommID = bcsub($sSteamComID, $sServer);
$sCommID = bcsub($sCommID, $steamBase);
$sAuth = bcdiv($sCommID, '2');
echo "$sServer:$sAuth";
}
convertToSteamID($sSteamComID);
This function outputs 0:15051912 on a server when it should be printing 1:15051908
The missing global $steamBase was the problem, as already mentioned in a comment. (Tip: turn on E_NOTICE during development.) However, I'd like to address your question:
I think it has something to do with
the numbers being too large, or
something to do with 64 bit. Is there
any way I can convert them so that
they would work correctly?
PHP integers are signed and platform-dependent. Using 64-bit numbers will not work if you are on a 32-bit host.
So your concern is valid. But even on a 64-bit system:
$x = 9223372036854775808; // highest bit (64th) set
var_dump($x);
--> float(9.2233720368548E+18)
Note that PHP's BC Math routines operate on strings, not integers. Thus, you should be storing your big numbers as strings.
This will work around the potential problem of integers being converted to floats, which will happen even on your 64-bit environment if you are using large, unsigned integers.

Categories