Jump to content
과거의 기술자료(읽기 전용): https://tech.devgear.co.kr ×
과거의 기술자료(읽기 전용): https://tech.devgear.co.kr

2023년 파이 데이(Pi Day)를 기념한 델파이의 Pi 계산


Recommended Posts

 

미국에서는 오늘 즉 3월 14일이 'π 데이(파이, Pi, 원주율)'이다. 전통적으로 이날에는 파이, 패스츄리를 먹거나, Pi(원주율) 값을 계산한다. Pi는 수학적으로 무리수 상수이다.

spacer.png

원의 둘레를 펴는 모습을 보여주는 애니메이션으로, π 비율을 보여준다.
John Reid [CC BY-SA 3.0]가 위키피디아를 통해 편집

 

델파이 안에는, 파이가 내장 함수로 포함되어 있다. System 유닛을 안에는 해당 참조(reference)들이 있다. 하지만, 해당 정의(definition)는 없다. 부동 소수점 숫자로 3.141592653589793238라는 값이 들어있다. 아마, 여러분은 마지막 일부 숫자까지 보지는 않을 것이겠지만, 이 숫자는 심지어 NASA에서 사용하는 것보다 더 더 정밀하다. 하지만, 이론적인 수학에서는 그리고 재미 삼아, 이 보다 더 정밀한 값을 구해볼 수도 있다.

Pi는 무리수(irrational number)이다. 즉, 소수 부분은 끝없이 계속되며 반복되지 않는다. 따라서 Pi를 계산할 때 우리는 반복을 거치면서, 그 정밀도 즉 자릿수를 높일 수 있다. 구글은 최근 Pi를 100조 자릿수까지 계산했다. 이를 위해 157일 23시간 31분 7.651초가 소요되었는데, 128 vCPU를 사용했으며, 864 GB RAM, 515 TB 저장소, 82 PB I/O를 활용했다. 구글은 이것을 구글의 클라우드 컴퓨팅 능력을 자랑하는 기회로 삼았다. 실용적으로 사용하려면, 그저 계산된 숫자를 한 것이다. 실용적인 사람이라면 그저 이미 계산된 값을 필요한 자릿수까지만 받으면 된다 (100조 미만까지는 제공되니 말이다).

Pi를 계산하는 방법을 보자면, 이미 여러 가지 알고리즘들이 있다. 우리 중 대다수는 아마 어느 정도 숫자까지 즉 일부 근사값까지 외우고 있을 것이다. 하지만 그 이상을 계산하고 싶다면 어떨까? 나는 웹을 뒤져보고, 심지어 Wolfram Alpha와 ChatGPT의 도움도 받아 보았다. 그 내용들을 모아서 몇 가지 예제를 통해 여러분에게 공유하고자 한다.

 

spacer.png

 

목차


 

라이프니츠의 파이 공식(Leibniz’s Formula for Pi)

고프트리트 라이프니츠(Gottfried Leibniz)의 이름을 딴 공식이다.  14세기쯤에 만들어졌다. 나는 델파이로 된 몇 가지 예제를 찾아서, 다음과 같이 구현해보았다:

function LeibnizPi(const Iterations: NativeUInt): Extended;
begin
  Result := 0;
  var k: Extended := 1;
  for var I := 0 to Iterations do
  begin
    if odd(I) then
      Result := Result - 4 / k
    else
      Result := Result + 4 / k;
    k := k + 2;
  end;
end;

위 구현의 결과는 다소 속도가 느리고 정밀도가 낮았다. 이 함수를 MaxInt까지 반복 실행했을 때, 계산된 결과 값은 3.14159265312413이다. 단지  소수점 이하 9자리까지만 정확하다. 

 

닐칸타에 대하여(Talking to Nilkantha)

내 메모에 닐칸타(Bilkantha)라고 적어놓긴 했었데, 확실하지는 않다. 다만 이 함수는 라이프니츠보다 조금 더 정확했다. 게다가 시간도 덜 걸렸다.

function NilkanthaPi(const Iterations: NativeUInt): Extended;
begin
  Result := 3;
  var n: Extended := 2;
  var sign := 1;
  for var I := 0 to Iterations do
  begin
    Result := Result + sign * (4 / (n * (n + 1) * (n + 2)));
    sign := sign * -1;
    n := n + 2;
  end;
end;

반복 시행 횟수(Iterations 파라미터)를 1,000으로 지정하면 소수점 이하 9자리까지, 11,000으로 지정하면 소수점 이하 12자리까지 정확하다.

이 알고리즘의 정확한 이름을 알고 있다면, 나에게 알려주기 바란다.

 

베일리-보르웨인-플루프 파이 공식(BBP, The Bailey–Borwein–Plouffe Pi Forumula)

BBP 공식은 1995년 사이먼 플러프(Simon Plouffe)가 발견했다. 이 BBP 공식은 스피곳(spigot) 알고리즘을 사용하여 π의 16진수를 n번째까지 계산한다 (π의 바이너리 숫자로는 4n번째 자리까지에 해당한다). 이 공식을 델파이 코드로 변환하려고 시작하면서, 이 기회를 ChatGPT에서 줘보기로 했다. 그랬더니, 쓸모있는 코드에 매우 가깝게 만들어 주었다. 살짝 다듬어서 다음과 같은 코드를 완성할 수 있었다:

function BaileyBorweinPlouffePi(const Digits: NativeUInt): Extended;
begin
  Result := 0;
  for var I := 0 to Digits do
  begin
    Result := Result + 1 / power(16, I) *
      ((4 / (8 * I + 1)) - (2 / (8 * I + 4)) - (1 / (8 * I + 5)) -
      (1 / (8 * I + 6)));
  end;
end;

속도가 굉장히 빨랐다. 그리고, 10자리 숫자를 표시하기에 충분했다.

 

루디의 Big Decimals 활용하기(Enter Rudy Big Decimals)

10자리 이상의 정밀도를 원한다면 어떻게 할까? 루디 벨트하위스(Rudy Velthuis)의 BigNumbers 라이브러리를 활용하면 된다. 현재 깃허브(GitHub)에서 받을 수 있다. 그곳에는 BigIntegers, BigDecimals, BigRationals 등 여러 유용한 라이브러리들이 있다. 나는 BBP 알고리즘이 BigDecimals을 사용하도록 변환했고, 그 결과는 다음과 같다: 

function BigBaileyBorweinPlouffePi(const Digits: NativeUInt): BigDecimal;
begin
  const sixteen = BigDecimal.Create(16);
  Result := BigDecimal.Zero;
  Result.DefaultPrecision := Digits;
  for var I := 0 to Digits do
  begin
    var
    term1 := BigDecimal.Create((4 / (8 * I + 1)) - (2 / (8 * I + 4)) -
      (1 / (8 * I + 5)) - (1 / (8 * I + 6)));
    var
    term2 := BigDecimal.Divide(1, sixteen.IntPower(I), Result.DefaultPrecision);
    Result := Result + BigDecimal.Multiply(term1, term2);
  end;
end;

여전히 속도가 매우 빠르다. 하지만, 아쉽게도, 여전히 약 20자리까지만 결과가 정확했다.

 

결론

델파이에 내장되어 있는 pi는 사용하기에 충분하다. 하지만, 델파이를 사용해 pi를 생성하는 코드를 바닥부터 만드는 방법을 살펴보는 것은 좋은 기회이다. 그 코드들을 깃허브 Gist에 올려두었다. 테스트를 더 해보고 피드백을 받으면 그 코드들도 업데이트할 예정이다. 더 큰 정수나 소수가 필요하다면 루디의 라이브러리를 살펴보기 바란다.

[전체 코드 보기]

이 댓글 링크
다른 사이트에 공유하기

  • RAD changed the title to 2023년 파이 데이(Pi Day)를 기념한 델파이의 Pi 계산

이 토의에 참여하세요

지금 바로 의견을 남길 수 있습니다. 그리고 나서 가입해도 됩니다. 이미 회원이라면, 지금 로그인하고 본인 계정으로 의견을 남기세요.

Guest
이 토픽(기고/질문)에 답하기

×   서식있는 텍스트로 붙여넣기.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   이전에 작성한 콘텐츠가 복원되었습니다..   편집창 비우기

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

중요한 정보

이용약관 개인정보보호정책 이용규칙 이 사이트가 더 잘 작동하기 위해 방문자의 컴퓨터에 쿠키가 배치됩니다. 쿠키 설정 변경에서 원하는 설정을 할 수 있습니다. 변경하지 않으면 쿠키를 허용하는 것으로 이해합니다.