PHP üzerinde 64 bit tamsayı olması nasıl?

4 Cevap php

Birisi PHP üzerinde 64 bit tamsayı olması için nasıl biliyor? config dosyası tarafından değil daha ziyade bir derleme zamanı seçenek olabilir gibi görünüyor ve bu platforma bağlıdır?

4 Cevap

Native 64-bit tamsayı 64-bit donanım VE PHP 64-bit sürümünü gerektirir.

32-bit donanım üzerinde:

$ php -r 'echo PHP_INT_MAX;'
2147483647

64-bit donanım üzerinde:

$ php -r 'echo PHP_INT_MAX;'
9223372036854775807

Donanım ve PHP hem de 64-bit bile Windows üzerinde o PHP, tüm 64-bit tamsayı desteklemez. this link ayrıntılar için bkz:

On windows x86_64, PHP_INT_MAX is 2147483647. This is because in the underlying c-code, a long is 32 bit.

However, linux on x86_64 uses a 64bit long so PHP_INT_MAX is going to be 9223372036854775807.

Belki kullanabilirsiniz GMP veya BCMath uzantısı olabilir.

PHP int boyut platforma bağlıdır. Aslında PHP değişkenlere ikili dizeleri farklı veri türlerini dönüştürmek olanak açmak adında bir function () vardır. Bu 64 bit bir dize olarak depolamak için olduğu gibi saklamak için tek yol gibi görünüyor.

I found the following code at: http://www.mysqlperformanceblog.com/2007/03/27/integers-in-php-running-with-scissors-and-portability/

/// portably build 64bit id from 32bit hi and lo parts
function _Make64 ( $hi, $lo )
{

        // on x64, we can just use int
        if ( ((int)4294967296)!=0 )
            return (((int)$hi)<<32) + ((int)$lo);

        // workaround signed/unsigned braindamage on x32
        $hi = sprintf ( "%u", $hi );
        $lo = sprintf ( "%u", $lo );

        // use GMP or bcmath if possible
        if ( function_exists("gmp_mul") )
            return gmp_strval ( gmp_add ( gmp_mul ( $hi, "4294967296" ), $lo ) );

        if ( function_exists("bcmul") )
            return bcadd ( bcmul ( $hi, "4294967296" ), $lo );

        // compute everything manually
        $a = substr ( $hi, 0, -5 );
        $b = substr ( $hi, -5 );
        $ac = $a*42949; // hope that float precision is enough
        $bd = $b*67296;
        $adbc = $a*67296+$b*42949;
        $r4 = substr ( $bd, -5 ) +  + substr ( $lo, -5 );
        $r3 = substr ( $bd, 0, -5 ) + substr ( $adbc, -5 ) + substr ( $lo, 0, -5 );
        $r2 = substr ( $adbc, 0, -5 ) + substr ( $ac, -5 );
        $r1 = substr ( $ac, 0, -5 );
        while ( $r4>100000 ) { $r4-=100000; $r3++; }
        while ( $r3>100000 ) { $r3-=100000; $r2++; }
        while ( $r2>100000 ) { $r2-=100000; $r1++; }

        $r = sprintf ( "%d%05d%05d%05d", $r1, $r2, $r3, $r4 );
        $l = strlen($r);
        $i = 0;
        while ( $r[$i]=="0" && $i<$l-1 )
            $i++;
        return substr ( $r, $i );         
    }

    list(,$a) = unpack ( "N", "\xff\xff\xff\xff" );
    list(,$b) = unpack ( "N", "\xff\xff\xff\xff" );
    $q = _Make64($a,$b);
    var_dump($q);