> On 3 Feb 2015, at 15:12, Leigh <lei...@gmail.com> wrote:
> 
> On 3 February 2015 at 15:02, Andrea Faulds <a...@ajf.me> wrote:
>> Why would it be promoted?! The high bit is the 63rd bit. It fits within a 
>> long.
>> 
> 
> I'm assuming your bigint implementation would want to respect signage.
> 
> When does it promote? 63rd to preserve signage?
> 
> 4611686018427387904 // 1 << 62 - int
> 9223372036854775808 // 1 << 63 - bigint
> 18446744073709551616 // 1 << 64 - bigint
> 
> Or 64th to for complete madness?
> 
> 4611686018427387904 // 1 << 62 - int
> -9223372036854775808 // 1 << 63 - int
> 18446744073709551616 // 1 << 64 - bigint

The specific code can be found here:

https://github.com/TazeTSchnitzel/php-src/blob/b91a80879ca3ba269bd239d9c820003c83d0dbc1/Zend/zend_operators.c#L2265

The algorithm is fairly simple: if the number of bits in the long plus the 
number of bits to shift is greater than the number of bits in a zend_long, then 
it promotes.

Thus:

$ sapi/cli/php -r '$x = 1 << 62; debug_zval_dump($x);'
long(4611686018427387904)
$ sapi/cli/php -r '$x = 1 << 63; debug_zval_dump($x);'
bigint(9223372036854775808) refcount(2)
$ sapi/cli/php -r '$x = 1 << 64; debug_zval_dump($x);'
bigint(18446744073709551616) refcount(2)

I tried some negative numbers, but I’ve noticed that any left shift on a 
negative integer promotes - that’s probably because clz is including the high 
bit... that should probably be fixed, mostly likely by doing clz on its 
absolute value in that case and factoring in the high bit.
--
Andrea Faulds
http://ajf.me/



--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to