복붙노트

PHP로 큰 숫자로 작업하기

PHP

PHP로 큰 숫자로 작업하기

많은 수의 (100,000+) Fermat Primality Test를 사용할 때 필요로하는 모듈러 멱계를 사용하려면 매우 큰 계산이 필요합니다.

두 개의 큰 숫자 (예 : 62574 및 62574)를 곱하면 PHP는 결과를 float로 캐스팅하는 것으로 보입니다. modulus 값을 구하는 것은 이상한 값을 반환합니다.

$x = 62574 * 62574;
var_dump($x);          // float(3915505476) ... correct
var_dump($x % 104659); // int(-72945)  ... wtf.

PHP가 이러한 계산을 올바르게 수행 할 수있는 방법이 있습니까? 양자 택일로, 큰 수를 위해 작동 할 계수 값을 찾아내는 또 다른 방법이 있습니까?

해결법

  1. ==============================

    1.어떤 이유로 PHP에서 임의의 길이 / 정밀도 숫자를 처리하는 두 개의 표준 라이브러리 인 BC Math와 GMP가 있습니다. 나는 더 신선하고 풍부한 API를 가지고 있기 때문에 개인적으로 GMP를 선호합니다.

    어떤 이유로 PHP에서 임의의 길이 / 정밀도 숫자를 처리하는 두 개의 표준 라이브러리 인 BC Math와 GMP가 있습니다. 나는 더 신선하고 풍부한 API를 가지고 있기 때문에 개인적으로 GMP를 선호합니다.

    GMP를 기반으로 통화량 저장 및 처리를 위해 Decimal2 클래스를 구현했습니다 (예 : USD 100.25). 거기 mod 계산의 많은 모든 문제가 없습니다. 매우 큰 숫자로 테스트되었습니다.

  2. ==============================

    2.이것을 사용하십시오.

    이것을 사용하십시오.

     $num1 = "123456789012345678901234567890";
     $num2 = "9876543210";
     $r    = mysql_query("Select @sum:=$num1 + $num2");
     $sumR = mysql_fetch_row($r);
     $sum  = $sumR[0];
    
  3. ==============================

    3.bcmod ()를 보셨습니까? php는 32 비트 플랫폼에서 2 ^ 31-1 이상의 정수에 문제가 있습니다.

    bcmod ()를 보셨습니까? php는 32 비트 플랫폼에서 2 ^ 31-1 이상의 정수에 문제가 있습니다.

    var_dump(bcmod("$x", '104659') ); // string(4) "2968"
    
  4. ==============================

    4.BigInteger를 사용해 보는 것이 좋습니다. 그래도 문제가 해결되지 않으면 SWIG를 사용하여 큰 정수 계산에 C / C ++ 코드를 추가하고이를 코드에 연결할 수 있습니다.

    BigInteger를 사용해 보는 것이 좋습니다. 그래도 문제가 해결되지 않으면 SWIG를 사용하여 큰 정수 계산에 C / C ++ 코드를 추가하고이를 코드에 연결할 수 있습니다.

  5. ==============================

    5.다른 솔루션을 찾았지만 숫자는 문자열로 저장됩니다. 숫자로 다시 변환하면 기본 플랫폼의 정밀도로 제한됩니다. 32 비트 플랫폼에서 int 타입으로 표현할 수있는 가장 큰 int는 2,147,483,647입니다.

    다른 솔루션을 찾았지만 숫자는 문자열로 저장됩니다. 숫자로 다시 변환하면 기본 플랫폼의 정밀도로 제한됩니다. 32 비트 플랫폼에서 int 타입으로 표현할 수있는 가장 큰 int는 2,147,483,647입니다.

    /**
     * @param string $a
     * @param string $b
     * @return string
     */
    function terminal_add($a, $b){
        return shell_exec('echo "'.$a.'+'.$b.'"|bc');
    }
    
    // terminal_add("123456789012345678901234567890", "9876543210")
    // output: "123456789012345678911111111100"
    
  6. ==============================

    6.

    $x = 62574 * 62574;
    
    // Cast to an integer
    $asInt = intval($x);
    var_dump($asInt);
    var_dump($asInt % 104659);
    
    // Use use sprintf to convert to integer (%d), which will casts to string
    $asIntStr = sprintf('%d', $x);
    var_dump($asIntStr);
    var_dump($asIntStr % 104659);
    
  7. ==============================

    7.나는 큰 숫자의 경우 반드시 작동 할 수있는 아주 작은 코드를 작성했습니다.

    나는 큰 숫자의 경우 반드시 작동 할 수있는 아주 작은 코드를 작성했습니다.

    <?php
        $x = gmp_strval(gmp_mul("62574","62574")); // $x="3915505476"
        $mod=gmp_strval(gmp_mod($x,"104659"));  //$mod="2968"
    
        echo "x : ".$x."<br>";
        echo "mod : ".$mod;
    
        /* Output:
            x : 3915505476
            mod : 2968
        */
    ?>
    

    큰 숫자를 저장하기 위해 문자열을 사용하고 PHP에서 GMP 함수를 사용하기 만하면됩니다.

    공식적인 PHP 매뉴얼에서 좋은 GMP 함수를 확인할 수있다. http://php.net/manual/en/ref.gmp.php

  8. from https://stackoverflow.com/questions/211345/working-with-large-numbers-in-php by cc-by-sa and MIT license