해석 언어에서 매우 큰 정수로 작업 할 때 예기치 않은 결과


192

의 합을 얻으려고 1 + 2 + ... + 1000000000하지만 PHP와 Node.js 에서 재미있는 결과를 얻습니다 .

PHP

$sum = 0;
for($i = 0; $i <= 1000000000 ; $i++) {
    $sum += $i;
}
printf("%s", number_format($sum, 0, "", ""));   // 500000000067108992

Node.js

var sum = 0;
for (i = 0; i <= 1000000000; i++) {
    sum += i ;
}
console.log(sum); // 500000000067109000

정답은 다음을 사용하여 계산할 수 있습니다.

1 + 2 + ... + n = n(n+1)/2

정답 = 500000000500000000 이므로 다른 언어를 사용하기로 결정했습니다.

가다

var sum , i int64
for i = 0 ; i <= 1000000000; i++ {
    sum += i
}
fmt.Println(sum) // 500000000500000000

그러나 잘 작동합니다! PHP와 Node.js 코드에 어떤 문제가 있습니까?

아마도 이것은 해석되는 언어의 문제 일 것이므로 Go와 같은 컴파일 된 언어로 작동합니까? 그렇다면 Python 및 Perl과 같은 다른 해석 언어도 같은 문제가 있습니까?


36
php.net/manual/en/book.bc.php 이 필요합니다. 그렇지 않으면 지옥이 얼어 붙을 때까지 IEEE 754에 머리를 박살낼 것입니다.
tereško

5
PHP에서 큰 수 (예 : 64 비트)를 처리하려면 GMP 함수 (이 경우 gmp_add ())를 사용하십시오.
Jeffrey

113
슈퍼 효율성을 위해, 당신의 루프는 정말 1 대신 0에서 시작한다 : P
그레이엄 볼랜드

55
합 (1에서 N) = (N / 2) * (N + 1)
Phong

5
@Baba 0은 계산을위한 수퍼 플로우 스 (superflous)이므로 0에 0을 더하기 위해 루프를 추가로 반복 할 필요가 없습니다.
Brian Warshaw

답변:


155

파이썬 작동 :

>>> sum(x for x in xrange(1000000000 + 1))
500000000500000000

또는:

>>> sum(xrange(1000000000+1))
500000000500000000

파이썬의 int자동 long은 임의의 정밀도를 지원 하는 파이썬으로 승격합니다 . 32 또는 64 비트 플랫폼에서 정답을 생성합니다.

이는 플랫폼의 비트 폭보다 훨씬 큰 2를 2로 올리면 알 수 있습니다.

>>> 2**99
633825300114114700748351602688L

PHP에서 잘못된 값이 2 ** 32-1보다 큰 경우 PHP가 부동으로 승격하기 때문에 오류가 있음을 입증 할 수 있습니다.

>>> int(sum(float(x) for x in xrange(1000000000+1)))
500000000067108992

이것을 32 또는 64 비트 시스템에서 실행 했습니까?
Baba

4
Python ints가 오버플로가 아닌 임의의 정밀도로 자동 승격되므로 (32 대 64 비트) 상관없이 작동해야합니다. 너무 오래 걸릴 수 있습니다.
dawg

3
파이썬은 필요한 경우 긴 정수로 자동 전환하기 때문에 모든 시스템에서 파이썬이 작동합니다. 충분하지 않으면 큰 정수로 전환됩니다.
Alok Singhal

12
@ 0x499602D2 : 좀 가혹합니다. OP 자신이 투표했다. 그는 이것이 파이썬에서 비슷한 문제인지 구체적으로 물었습니다. 대답은 아닙니다. 그렇지 않다는 것을 보여주는 코드. WTH?
dawg

10
파이썬 예제는 너무 길다. sum (xrange (int (1e9) +1)) (.... sum은 iterables에서 작동한다)
Jason Morgan

101

Go 코드는 정확한 답을 제공하기에 충분한 비트를 가진 정수 산술을 사용합니다. PHP 나 Node.js를 만지지 않았지만 결과에서 수학은 부동 소수점 숫자를 사용하여 수행 된 것으로 생각 되므로이 크기의 숫자에는 정확하지 않아야합니다.


46
네. If PHP encounters a number beyond the bounds of the integer type, it will be interpreted as a float instead. Also, an operation which results in a number beyond the bounds of the integer type will return a float instead.- php.net/manual/en/language.types.integer.php
네이트

3
그리고 NodeJS (및 일반적인 JavaScript)에서 모든 산술 연산 (비트 연산 제외)은 마치 부동 소수점 숫자로 수행 된 것처럼 동작합니다. 이들이 실제로 존재하는지 여부는 개별 JavaScript 엔진의 결정에 따라 결정적인 차이가 있습니다.
피터 올슨

13
자바 스크립트 사양에는 정수 유형이 없습니다. 모든 숫자는 부동 소수점입니다.
toasted_flakes

8
@grasGendarme 있습니다. ES5 스펙 , 예를 들어, 비트 단위 시프트 로 호출 되는 다양한 정수 변환 및 명령을 지정합니다 . 다시 말해서, 배후에서 정수 유형은 Javascript에서 사용되지만 모든 산술 연산자는 연산을 수행하기 전에 피연산자를 부동 소수점 숫자로 변환합니다 (컴파일러 최적화 금지).
피터 올슨

2
여기에 내가 int64가 아닌 float64를 사용했기 때문에 코드 가 엉망인 것 같습니다. 그냥 32 비트 또는 64 비트와 관련이 없음을 확인했습니다
Baba

45

정수 변수의 sum값이 최대 값을 초과 하기 때문입니다 . 그리고 sum당신은 반올림을 포함하는 부동 소수점 산술의 결과입니다. 다른 답변은 정확한 한계를 언급하지 않았으므로 게시하기로 결정했습니다.

다음에 대한 PHP의 최대 정수 값 :

  • 32 비트 버전은 2147483647입니다.
  • 64 비트 버전은 9223372036854775807입니다.

따라서 32 비트 CPU 또는 32 비트 OS 또는 32 비트 컴파일 버전의 PHP를 사용하고 있음을 의미합니다. 를 사용하여 찾을 수 있습니다 PHP_INT_MAX. 는 sum64 비트 컴퓨터에 그것을 할 경우 정확하게 계산 될 것이다.

JavaScript의 최대 정수 값은 9007199254740992 입니다. 당신이 작업 할 수있는 가장 큰 정확한 적분 값은 2 53입니다 (이 질문 에서 취함 ). 는 sum이 제한을 초과합니다.

정수 값이이 한계를 초과하지 않으면 정상입니다. 그렇지 않으면 임의의 정밀 정수 라이브러리를 찾아야합니다.


28

완전성에 대한 C의 답은 다음과 같습니다.

#include <stdio.h>

int main(void)
{
    unsigned long long sum = 0, i;

    for (i = 0; i <= 1000000000; i++)    //one billion
        sum += i;

    printf("%llu\n", sum);  //500000000500000000

    return 0;
}

이 경우 핵심은 C99의 long long 데이터 유형을 사용하는 것입니다. C가 관리 할 수있는 가장 큰 기본 스토리지를 제공하며 실제로 매우 빠르게 실행됩니다 . 이 long long유형은 대부분의 32 비트 또는 64 비트 시스템에서도 작동합니다.

한 가지주의 사항이 있습니다. Microsoft에서 제공하는 컴파일러는 14 년 된 C99 표준을 명시 적으로 지원하지 않으므로 Visual Studio에서이 기능을 실행하면 문제가 발생합니다.


3
MSVC ++는 C ++ 컴파일러이며 C ++는 long longC ++ 11 표준을 따릅니다. 그러나 몇 년 동안 MSVC ++ 및 g ++ 확장이었습니다.
MSalters

1
@MSalters 따라서 C ++ 기능이기 때문에 누구나 직접 C 프로그램을 컴파일하는 데 도움이되지 않습니다. C에서 C ++로 전환을 시도한 적이 없으므로 해당 해결 방법이 실제로 작동하는지 알 수 없습니다.
CyberSkull 12

19
그리고 멋지게 최적화와 GCC 또는 연타가로 전체 루프를 설정movabsq $500000000500000000, %rsi
토르 Klingberg

3
그냥 gcc -O3또는 clang -O3. 특정 최적화의 이름을 모르겠습니다. 기본적으로 컴파일러는 루프의 결과가 인수에 의존하지 않으며 컴파일 타임에 계산한다는 것을 알고 있습니다.
Tor Klingberg

1
C99 long long은 최소 크기가 64 비트이며 32 비트 및 64 비트 플랫폼 모두에서 64 비트입니다. 쿼드 또는 옥토 정수에 대한 일반적인 지원을 보지 못했습니다.
Devin Lane

21

내 생각에 합계가 기본 용량 int(2 31 -1 = 2,147,483,647)을 초과하면 Node.js 및 PHP가 부동 소수점 표현으로 전환되고 반올림 오류가 발생하기 시작합니다. Go와 같은 언어는 아마도 가능한 한 오랫동안 정수 형식 (예 : 64 비트 정수)을 고수하려고합니다 (실제로 시작하지 않은 경우). 답은 64 비트 정수에 적합하므로 계산이 정확합니다.


Node.js에는 명시 적으로 int 유형이 없습니다. float 형식으로 작동합니다.
greyfade

@greyfade-예, 모든 EcmaScript 호환 환경에 해당되는 것 같습니다.
테드 홉

그렇지 않습니까 (2 ** 31-1)?
Zachary Hunter

@ZacharyHunter-그렇습니다. 그 오류를 잡아 주셔서 감사합니다.
Ted Hopp

19

펄 스크립트는 우리에게 예상되는 결과를줍니다 :

use warnings;
use strict;

my $sum = 0;
for(my $i = 0; $i <= 1_000_000_000; $i++) {
    $sum += $i;
}
print $sum, "\n";  #<-- prints: 500000000500000000

3
이것을 32 또는 64 비트 시스템에서 실행 했습니까?
Baba

2
64 비트 시스템에서 실행되었습니다
Miguel Prz

3
4.99999999067109e+017Perl v5.16.1 MSWin32-x86에서.
Qtax

7
큰 숫자가 정말로 필요한 경우 bignum또는을 사용하십시오 bigint. 둘 다 핵심 모듈입니다. 즉, Perl v5.8.0 이상과 함께 설치됩니다. 참조 http://perldoc.perl.org/bignum.htmlhttp://perldoc.perl.org/bigint.html
shawnhcorey

나는 Perl 5.12.4를 실행하는 32 비트 PPC Mac에서 이것을 실행하는 500000000500000000을 얻었습니다.
CyberSkull

17

이에 대한 대답은 "놀랍게도"간단합니다.

대부분의 아시다시피 32 비트 정수는 −2,147,483,648 에서 2,147,483,647 입니다. PHP가 결과를 얻는다면 어떻게됩니까?

보통 2,147,483,647 + 1−2,147,483,648 로 바뀌는 즉각적인 "오버 플로우"를 기대합니다 . 그러나 그렇지 않습니다. PHP가 더 큰 숫자를 만나면 INT 대신 FLOAT를 반환합니다.

PHP가 정수 유형의 범위를 벗어나는 숫자를 발견하면 대신 부동 소수점으로 해석됩니다. 또한 정수 유형의 범위를 넘어 숫자를 생성하는 연산은 대신 부동 소수점을 반환합니다.

http://php.net/manual/en/language.types.integer.php

PHP FLOAT 구현이 IEEE 754 배정 밀도 형식을 따른다는 것은 PHP가 정밀도를 잃지 않고 52 비트까지의 숫자를 처리 할 수 ​​있다는 것을 의미합니다. (32 비트 시스템에서)

따라서 합계가 9,007,199,254,740,992 ( 2 ^ 53 인 경우 )에서 PHP 수학에서 반환되는 Float 값은 더 이상 정확하지 않습니다.

E:\PHP>php -r "$x=bindec(\"100000000000000000000000000000000000000000000000000000\"); echo number_format($x,0);"

9,007,199,254,740,992

E:\PHP>php -r "$x=bindec(\"100000000000000000000000000000000000000000000000000001\"); echo number_format($x,0);"

9,007,199,254,740,992

E:\PHP>php -r "$x=bindec(\"100000000000000000000000000000000000000000000000000010\"); echo number_format($x,0);"

9,007,199,254,740,994

이 예제는 PHP가 정밀도를 잃는 지점을 보여줍니다. 첫째, 마지막 significatn 비트가 삭제되어 처음 두 표현식은 같은 수를 얻습니다.

NOW ON부터는 기본 데이터 형식으로 작업 할 때 전체 수학이 잘못됩니다.

파이썬이나 펄과 같은 다른 해석 언어의 경우에도 같은 문제입니까?

나는 그렇게 생각하지 않습니다. 나는 이것이 유형 안전이없는 언어의 문제라고 생각합니다. 위에서 언급 한 바와 같이 정수 오버 플로우는 고정 데이터 유형을 사용하는 모든 언어에서 발생하지만, 유형 안전이없는 언어는 다른 데이터 유형에서이를 포착하려고 시도 할 수 있습니다. 그러나 일단 "자연"(시스템 제공) 경계에 도달하면 올바른 결과를 제외한 모든 것을 반환 할 수 있습니다.

그러나 이러한 시나리오에 따라 언어마다 스레딩이 다를 수 있습니다.


15

다른 답변은 이미 여기서 일어나는 일을 설명했습니다 (평소와 같이 부동 소수점 정밀도).

한 가지 해결책은 충분히 큰 정수 유형을 사용하거나 필요한 경우 언어가 하나를 선택하기를 희망하는 것입니다.

다른 해결책은 정밀도 문제를 알고 해결하는 합산 알고리즘을 사용하는 것입니다. 아래에서 먼저 64 비트 정수를 사용한 다음 64 비트 부동 소수점을 사용한 다음 부동 소수점을 다시 사용하지만 Kahan 합계 알고리즘 을 사용하여 동일한 합계를 찾습니다 .

C #으로 작성되었지만 다른 언어에서도 마찬가지입니다.

long sum1 = 0;
for (int i = 0; i <= 1000000000; i++)
{
    sum1 += i ;
}
Console.WriteLine(sum1.ToString("N0"));
// 500.000.000.500.000.000

double sum2 = 0;
for (int i = 0; i <= 1000000000; i++)
{
    sum2 += i ;
}
Console.WriteLine(sum2.ToString("N0"));
// 500.000.000.067.109.000

double sum3 = 0;
double error = 0;
for (int i = 0; i <= 1000000000; i++)
{
    double corrected = i - error;
    double temp = sum3 + corrected;
    error = (temp - sum3) - corrected;
    sum3 = temp;
}
Console.WriteLine(sum3.ToString("N0"));
//500.000.000.500.000.000

카한 요약은 아름다운 결과를 제공합니다. 물론 계산하는 데 시간이 오래 걸립니다. 사용 여부는 a) 성능 대 정밀도 요구 사항 및 b) 언어가 정수 대 부동 소수점 데이터 유형을 처리하는 방법에 따라 다릅니다.


@Baba OP의 Node.js / JavaScript와 동일합니다. 500000000067109000 vs. 500000000067108992…
linac

아마도 바바는 천 단위 구분 기호에 점을 사용하는 것에 흥미를 느낍니다. 영어는 보통 쉼표를 기대합니다. 밑줄을보다 중립적 인 수단으로 사용할 수도 있습니다.
didierc

14

32 비트 PHP가있는 경우 bc로 계산할 수 있습니다 .

<?php

$value = 1000000000;
echo bcdiv( bcmul( $value, $value + 1 ), 2 );
//500000000500000000

Javascript에서는 임의의 숫자 라이브러리 (예 : BigInteger) 를 사용해야합니다 .

var value = new BigInteger(1000000000);
console.log( value.multiply(value.add(1)).divide(2).toString());
//500000000500000000

Go 및 Java와 같은 언어를 사용하더라도 결국 임의의 숫자 라이브러리를 사용해야 할 것입니다. 64 비트에 대해서는 작지만 32 비트에 대해서는 너무 높습니다.


12

루비에서 :

sum = 0
1.upto(1000000000).each{|i|
  sum += i
}
puts sum

인쇄 500000000500000000하지만 2.6GHz Intel i7에서는 4 분이 걸립니다.


Magnuss와 Jaunty는 훨씬 더 많은 루비 솔루션을 가지고 있습니다.

1.upto(1000000000).inject(:+)

벤치 마크를 실행하려면

$ time ruby -e "puts 1.upto(1000000000).inject(:+)"
ruby -e "1.upto(1000000000).inject(:+)"  128.75s user 0.07s system 99% cpu 2:08.84 total

10
1.upto (1000000000) .inject (: +)
Magnuss

@ Magnuss : 처음에 시도한 것으로 생각되었지만 엄청난 메모리 누수가 발생했습니다. 당신은 작동하는 것 같습니다 ...
cgenco

11

나는 큰 정수 물건에 node-bigint를 사용합니다 :
https://github.com/substack/node-bigint

var bigint = require('bigint');
var sum = bigint(0);
for(var i = 0; i <= 1000000000; i++) { 
  sum = sum.add(i); 
}
console.log(sum);

이 정확한 테스트를 위해 기본 64 비트를 사용할 수있는 것만 큼 빠르지는 않지만 64 비트보다 큰 수에 도달하면 후드 아래에서 libgmp를 사용합니다. 이는 임의의 빠른 정밀 라이브러리 중 하나입니다.


4

루비로 나이를 먹었지 만 정답을 제공합니다.

(1..1000000000).reduce(:+)
 => 500000000500000000 

4

PHP에서 올바른 결과를 얻으려면 BC 수학 연산자를 사용해야한다고 생각합니다. http://php.net/manual/en/ref.bc.php

스칼라의 정답입니다. Longs를 사용해야합니다. 그렇지 않으면 숫자가 오버플로됩니다.

println((1L to 1000000000L).reduce(_ + _)) // prints 500000000500000000

3

실제로이 문제에는 멋진 트릭이 있습니다.

대신 1-100이라고 가정하십시오.

1 + 2 + 3 + 4 + ... + 50 +

100 + 99 + 98 + 97 + ... + 51

= (101 + 101 + 101 + 101 + ... + 101) = 101 * 50

공식:

N = 100의 경우 : 출력 = N / 2 * (N + 1)

N = 1e9의 경우 : 출력 = N / 2 * (N + 1)

이것은 모든 데이터를 반복하는 것보다 훨씬 빠릅니다. 프로세서가 고맙습니다. 이 문제에 관한 흥미로운 이야기가 있습니다.

http://www.jimloy.com/algebra/gauss.htm


11
칼리닌그라드의 Pregel을 가로 지르는 다리를 두 번 건너지 않고 걸을 수 있다고 생각하십니까? 많은 사람들이 시도하고 실패했지만 아무도 불가능하다는 것을 아직 확립하지 못했습니다. 이것은 당신이 해결할 수있는 유일무이 한 도전 인 것 같습니다.
jwg

3

이것은 정수 캐스트를 강제함으로써 PHP에서 적절한 결과를 제공합니다.

$sum = (int) $sum + $i;

3

Common Lisp는 가장 빠르게 해석되는 언어 중 하나이며 기본적으로 임의로 큰 정수를 올바르게 처리합니다. SBCL을 사용 하면 약 3 초가 걸립니다 .

* (time (let ((sum 0)) (loop :for x :from 1 :to 1000000000 :do (incf sum x)) sum))

Evaluation took:
  3.068 seconds of real time
  3.064000 seconds of total run time (3.044000 user, 0.020000 system)
  99.87% CPU
  8,572,036,182 processor cycles
  0 bytes consed

500000000500000000
  • 해석하면 REPL 에서이 코드를 실행했지만 SBCL은 내부적으로 JITing을 수행하여 빠르게 실행되도록 할 수는 있지만 코드를 즉시 실행하는 동적 경험은 동일합니다.

(시간 (1에서 1000000000 sum x까지의 루프))로 단순화 할 수 있습니다. 선언을 추가하여 ~ 5 배 속도를 얻었습니다 : (시간 (로컬 (((속도 3) 최적화 (안전성 0))) (타입 고정 번호의 루프는 1에서 1000000000까지의 합계 i는 유형 고정 번호))
huaiyuan

이것은 잘못된 것입니다. 다른 언어로 눈을 멀게하지 마십시오! lisp에 쓰는 올바른 방법은 다음과 같습니다. (defun sum-to-1-n (n) (/ (* n (1+ n)) 2)) (time (sum-from-1-to-n 1000000000)) 실행하는 데 14 마이크로 초 (0.000014 초)가 걸렸습니다. 그 기간 동안, 그리고 4 개 사용 가능한 CPU 코어, 0 마이크로 초 (0.000000 초) 0 마이크로 초 (0.000000 초) 시스템 모드에서 소비 된 사용자 모드에서 소비되었다 -> 500000000500000000
informatimago

@informatimago : 오류가 아닙니다. 나는 질문의 명령형 루프 스타일을 복사하고 있었고 많은 사람들이 지적했듯이 질문 자체는 더 쉬운 계산 방법이 있다고 언급합니다. Chillax.
postfuturist

3

@postfuturist의 Common Lisp 답변에 대해 언급 할만 큼 평판이 좋지 않지만 내 컴퓨터에서 SBCL 1.1.8로 ~ 500ms 안에 완료하도록 최적화 할 수 있습니다.

CL-USER> (compile nil '(lambda () 
                        (declare (optimize (speed 3) (space 0) (safety 0) (debug 0) (compilation-speed 0))) 
                        (let ((sum 0))
                          (declare (type fixnum sum))
                          (loop for i from 1 to 1000000000 do (incf sum i))
                          sum)))
#<FUNCTION (LAMBDA ()) {1004B93CCB}>
NIL
NIL
CL-USER> (time (funcall *))
Evaluation took:
  0.531 seconds of real time
  0.531250 seconds of total run time (0.531250 user, 0.000000 system)
  100.00% CPU
  1,912,655,483 processor cycles
  0 bytes consed

500000000500000000

3

라켓 v 5.3.4 (MBP; 시간은 ms) :

> (time (for/sum ([x (in-range 1000000001)]) x))
cpu time: 2943 real time: 2954 gc time: 0
500000000500000000

1
6 분 후에 답변을 삭제 한 후 6 분 후에 답변이 삭제되었습니다. :)
Greg Hendershott

3

Rebol에서 잘 작동합니다.

>> sum: 0
== 0

>> repeat i 1000000000 [sum: sum + i]
== 500000000500000000

>> type? sum
== integer!

이것은 32 비트 컴파일되었지만 64 비트 정수를 사용하는 Rebol 3을 사용했습니다 (32 비트 정수를 사용한 Rebol 2와 달리)


3

CF Script에서 무슨 일이 있었는지보고 싶었습니다

<cfscript>
ttl = 0;

for (i=0;i LTE 1000000000 ;i=i+1) {
    ttl += i;
}
writeDump(ttl);
abort;
</cfscript>

나는 5.00000000067E + 017을 얻었다

이것은 꽤 깔끔한 실험이었습니다. 더 많은 노력으로 이것을 조금 더 잘 코딩 할 수 있다고 확신합니다.


3

32 비트 윈도우의 ActivePerl v5.10.1, Intel Core2duo 2.6 :

$sum = 0;
for ($i = 0; $i <= 1000000000 ; $i++) {
  $sum += $i;
}
print $sum."\n";

결과 : 5 분 안에 5.00000000067109e + 017.

"bigint 사용"스크립트를 사용하면 2 시간 동안 작동했고 더 많이 작동했지만 중단했습니다. 너무 느린.


bigints를 추가하는 데 시간이 얼마나 걸리는지 누구나 확인할 수 있습니까?
jwg

3

Clojure에서 완전성을 위해 (아름답지만 효율적이지 않음) :

(reduce + (take 1000000000 (iterate inc 1))) ; => 500000000500000000

1
$ MY_FAVOURITE_LANGUAGE 답변에 유일하게 유용한 정보는 결과를 제공하는 것입니다.
jwg

@ jwg 예 죄송합니다. 업데이트 된 답변을 놓쳤습니다.
Blacksad

3

AWK :

BEGIN { s = 0; for (i = 1; i <= 1000000000; i++) s += i; print s }

PHP와 동일한 잘못된 결과를 생성합니다.

500000000067108992

숫자가 실제로 클 때 AWK는 부동 소수점을 사용하는 것처럼 보이므로 적어도 대답은 올바른 크기 순서입니다.

시운전 :

$ awk 'BEGIN { s = 0; for (i = 1; i <= 100000000; i++) s += i; print s }'
5000000050000000
$ awk 'BEGIN { s = 0; for (i = 1; i <= 1000000000; i++) s += i; print s }'
500000000067108992

2

다른 해석 언어 카테고리 :

Tcl :

Tcl 8.4 이상을 사용하는 경우 32 비트 또는 64 비트로 컴파일되었는지 여부에 따라 다릅니다. (8.4는 수명이 끝났습니다).

임의의 큰 정수를 가진 Tcl 8.5 이상을 사용하면 올바른 결과가 표시됩니다.

proc test limit {
    for {set i 0} {$i < $limit} {incr i} {
        incr result $i
    }
    return $result
}
test 1000000000 

바이트 컴파일을 위해 테스트를 proc 안에 넣었습니다.


2

PHP 코드의 답은 다음과 같습니다.

정수의 크기는 플랫폼에 따라 다르지만 최대 약 20 억 개의 값이 일반적인 값 (32 비트 부호)입니다. 64 비트 플랫폼의 최대 값은 일반적으로 약 9E18입니다. PHP는 부호없는 정수를 지원하지 않습니다. 정수 크기는 PHP_INT_SIZE 상수를 사용하여, PHP 4.4.0 및 PHP 5.0.5 이후 PHP_INT_MAX 상수를 사용하여 최대 값을 결정할 수 있습니다.


2

항구:

proc Main()

   local sum := 0, i

   for i := 0 to 1000000000
      sum += i
   next

   ? sum

   return

의 결과입니다 500000000500000000. (windows / mingw / x86 및 osx / clang / x64)


2

얼랭의 작품 :

from_sum(From,Max) ->
    from_sum(From,Max,Max).
from_sum(From,Max,Sum) when From =:= Max ->
    Sum;
from_sum(From,Max,Sum) when From =/= Max -> 
    from_sum(From+1,Max,Sum+From).

결과 : 41> 쓸모없는 : from_sum (1,1000000000). 500000000500000000


2

재미있는 점은 PHP 5.5.1은 499999999500000000 (~ 30 초)을 제공하는 반면 Dart2Js는 500000000067109000 (JS가 실행되므로 예상 됨)을 제공합니다. CLI Dart는 정답을 즉시 제공합니다 ...


2

Erlang도 예상 결과를 제공합니다.

sum.erl :

-module(sum).
-export([iter_sum/2]).

iter_sum(Begin, End) -> iter_sum(Begin,End,0).
iter_sum(Current, End, Sum) when Current > End -> Sum;
iter_sum(Current, End, Sum) -> iter_sum(Current+1,End,Sum+Current).

그리고 그것을 사용 :

1> c(sum).
{ok,sum}
2> sum:iter_sum(1,1000000000).
500000000500000000

2

잡담:

(1 to: 1000000000) inject: 0 into: [:subTotal :next | subTotal + next ]. 

"500000000500000000"
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.