> 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