최고의 (휴대용) 크로스 플랫폼 임의 정밀도 수학 라이브러리는 무엇입니까? [닫은]


81

C 또는 C ++에서 좋은 임의 정밀도 수학 라이브러리를 찾고 있습니다. 제게 조언이나 제안을 주시겠습니까?

기본 요구 사항 :

  1. 그것은 해야한다 임의의 큰 정수를-내 처리 주요 관심사는 정수에 있습니다. 임의로 큰 단어가 무엇을 의미하는지 모르는 경우 100000과 같은 것을 상상해보십시오! (100000의 계승).

  2. 정밀도 라이브러리 초기화 또는 오브젝트 작성 중에 지정 될 필요가 없습니다 . 정밀도는 시스템의 사용 가능한 리소스에 의해서만 제한 되어야 합니다.

  3. 그것은 해야 플랫폼의 모든 기능을 활용하고, 기본적으로 "작은"숫자를 처리해야합니다. 즉, 64 비트 플랫폼에서 (2 ^ 33 + 2 ^ 32) 계산시 사용 가능한 64 비트 CPU 명령어를 사용해야합니다. 라이브러리 동일한 플랫폼에서 (2 ^ 66 + 2 ^ 65)와 동일한 방식으로이를 계산 해서는 안됩니다 .

  4. 그것은 해야 효율적 또한 핸들 ( +) 감산 ( -), 승산 ( *), 정수 나눗셈 ( /), 나머지 ( %), 전력 ( **), 증분 ( ++), 감소 ( --) GCD, 요인 및 기타 일반적인 산술 연산 정수. 정수 결과를 생성하지 않는 제곱근 및 로그와 같은 함수를 처리하는 기능은 플러스입니다. 기호 계산 을 처리하는 기능 이 훨씬 더 좋습니다.

지금까지 찾은 내용은 다음과 같습니다.

  1. JavaBigIntegerBigDecimal 클래스 : 지금까지 사용하고 있습니다. 소스 코드를 읽었지만 밑에있는 수학을 이해하지 못합니다. 내가 배운 적이없는 이론과 알고리즘을 기반으로 할 수 있습니다.

  2. 내장 정수 유형 또는 bc , Python , Ruby , Haskell , Lisp , Erlang , OCaml , PHP , 일부 다른 언어의 핵심 라이브러리 : 이들 중 일부를 사용했지만 어떤 라이브러리를 사용하고 있는지 모르겠습니다. 어떤 종류의 구현을 사용하고 있는지.

내가 이미 알고있는 것 :

  1. 사용 char진수과 char*진수 문자열 및 사용하여 숫자에 대한 계산을 할 for-loop합니다.

  2. 사용 int(또는 long int, 또는 long long기본적인 "유닛"및 임의의 길이의 정수와 같은 유형의 배열로), 및 사용 요소에 연산을 수행 for-loop한다.

  3. 정수 유형을 사용하여 십진수 (또는 몇 자릿수)를 BCD (이진 코드 십진수)로 저장 합니다.

  4. 부스의 곱셈 ​​알고리즘 .

내가 모르는 것 :

  1. 순진한 방법을 사용하지 않고 위에서 언급 한 이진 배열을 십진수로 인쇄합니다. 순진한 방법의 예 : (1) 가장 낮은 char*것부터 가장 높은 것까지 비트를 추가합니다 : 1, 2, 4, 8, 16, 32,… (2) 중간 10 진수 결과를 저장하기 위해 위에서 언급 한 문자열을 사용합니다 ).

감사합니다 :

  1. GMP , MPFR , decNumber (또는 귀하의 의견에 좋은 다른 라이브러리) 에 대한 좋은 비교 .

  2. 내가 읽어야 할 책과 기사에 대한 좋은 제안. 예를 들어, 순진하지 않은 2 진수에서 10 진수로 변환 알고리즘이 작동 하는 방식에 대한 그림이있는 그림 이 좋습니다. 이 기사 " 제한 정밀의 진수 변환에 진 더글러스 W. 존스는"좋은 기사의 예입니다.

  3. 일반적인 도움.

제발 하지 않는 사용이라고 생각하면이 질문에 대답 double(또는 long double, 또는 long long double) 쉽게이 문제를 해결할 수 있습니다. 그렇게 생각한다면 문제의 문제를 이해하지 못하는 것입니다.


3
내가 볼 수있는 한, GMP는 좋은 라이브러리 인 것 같습니다. 내가 궁금한 것은 Python / Haskell / Erlang / etc의 기여자가 바퀴를 다시 발명해야하는 이유입니다. GMP가 그렇게 좋다면 왜 그것에 의존하지 않습니까? GPL / LGPL 라이선스가 문제 중 하나 일 수 있지만이 문제 (및 반올림 모드 문제)에도 불구하고 GMP의 다른 단점이 있습니까? Python / Haskell / Erlang / 모든 암호화 라이브러리의 내장 정수가 GMP보다 빠릅니까? 그렇다면 라이선스가 허용하는 경우 추출하여 사용하고 싶습니다.
Siu Ching Pong -Asuka Kenji- 2010

Douglas W. Jones의 cs.uiowa.edu/~jones/bcd/decimal.html 에서 멋진 기사를 찾았 습니다. 이 기사에서는 8 비트 정수 산술 만 사용하여 16 비트 정수를 10 진수 표현으로 변환하는 방법을 설명합니다. 아이디어는 16 비트 숫자를 각각 16 진수 "숫자"를 나타내는 4 개의 니블로 나누는 것입니다. 따라서 digit-0 (n0)은 x1, n1 => x16, n2 => x256, n3 => x4096을 나타냅니다. 그러면 10 진수 (d0)의 digit-0이 n0 * 1 + n1 * 6 + n2 * 6 + n3 * 6의 결과의 digit-0임을 알 수 있습니다. 캐리를 올바르게 처리하면 d1 ~ d4가 또한 계산됩니다.
Siu Ching Pong -Asuka Kenji- 2010

그러나 내가 상상할 수있는 한, 위의 Douglas의 아이디어는 임의의 긴 이진 정수를 처리하도록 확장 될 수 없습니다. 숫자 1 (16 ^ 0), 16 (16 ^ 1), 256 (16 ^ 2), 4096 (16 ^ 3)이 미리 계산되기 때문입니다. 그러면 문제는 임의로 큰 n에 대해 16 ^ n을 십진수로 표현하는 방법이됩니다.
Siu Ching Pong -Asuka Kenji- 2010

답변:


24

GMP는 대중적인 선택입니다. Squeak Smalltalk에는 매우 멋진 라이브러리가 있지만 Smalltalk로 작성되었습니다.

관련 책이나 기사를 요청했습니다. bignums의 까다로운 부분은 긴 나눗셈입니다. Per Brinch Hansen의 논문 Multiple-Length Division Revisited : A Tour of the Minefield를 추천 합니다.


논문 링크에 감사드립니다! 네, 분할이 가장 까다로운 부분이라는 데 동의합니다. 나는 오래 전에 "종이와 연필 방법"을 사용하여 손으로 나누는 방법을 알고 있었기 때문에 char *(각각 10 진수를 나타내는) 십진수 문자열 char또는 int *BCD 문자열 ( )에 동일한 방법을 적용 할 수 있습니다. 각각 int4/8/16 BCD 숫자를 나타냄). 그러나 실제 프로덕션 수준의 라이브러리가 너무 느리기 때문에 "종이와 연필 방식"을 모방하는지 궁금합니다.
Siu Ching Pong -Asuka Kenji- 2010

그 이유를 알아보기 위해 어떻게 실행되는지 상상해 봅시다 100,000,000,000,000,000 / 333,333,333,333. 첫 번째 단계는와 비교 100,000,000,000하는 것 333,333,333,333입니다. 전자가 후자보다 작기 때문에 계산은 단순히 다음 숫자로 이동합니다. 두 번째 단계는의 몫을 찾는 것입니다 1,000,000,000,000 / 333,333,333,333. 여기에는 333,333,333,333 * 1(and * 2, * 3and * 4) 의 시행 착오 곱셈 또는 루프에서 연속 뺄셈을 수행하는 것이 포함됩니다. 얼마나 느린 지 보십니까? 더 효율적인 알고리즘이 있다고 생각합니다.
Siu Ching Pong -Asuka Kenji- 2010

3
@Sui : Brinch Hanson이 시행 착오 방법을 최대 두 번의 시행으로 줄일 수있는 방법을 보여줍니다. 정말 인상적입니다.
Norman Ramsey

좋아요, 논문을 좀 더 자세히 살펴 보겠습니다. 감사합니다!
Siu Ching Pong -Asuka Kenji- 2010

1
솔루션을 어디에서 찾았는지, 숫자를 저장하는 데 사용한 형식은 확실하지 않지만 COBOL의 COMP-3 니블 형식은 처리하기가 훨씬 더 좋습니다. 값, 그리고 사용 가능한 숫자를 얻기 위해 ASCII char 값에서 16 진수 30을 뺄 필요가 없습니다.

13

전반적으로 가장 빠른 범용 임의 정밀도 라이브러리는 GMP 입니다. 부동 소수점 값으로 작업하려면 MPFR 라이브러리를 살펴보십시오 . MPFR은 GMP를 기반으로합니다.

다른 언어의 기본 임의 정밀도 지원과 관련하여 Python은 라이센스, 코드 크기 및 코드 이식성 이유로 인해 자체 구현을 사용합니다. GMPY의 모듈은 GMP 라이브러리 파이썬에 액세스 할 수 있습니다.


당신의 응답을 주셔서 감사합니다! "코드 이식성"을 언급하셨습니다. 문제가 무엇인지 설명해 주시겠습니까? GMP는 이식 가능하고 주요 플랫폼에서 지원된다고 생각했습니다 ...
Siu Ching Pong -Asuka Kenji- 2010

2
"코드 이식성"은 "주요 플랫폼에서 지원"과는 다릅니다. Python은 C 컴파일러의 동작에 대해 거의 가정하지 않는 간단한 구현을 사용하므로 거의 모든 C 컴파일러에서 동일한 코드를 컴파일 할 수 있습니다. GMP는 더 많은 코드 (C 및 고도로 조정 된 어셈블리)를 사용하여 GMP를 더 빠르게 만들지 만 C 컴파일러 및 어셈블러의 동작에 대해 더 많은 가정을합니다. 예를 들어 GMP는 Microsoft Visual Studio 컴파일러에서 잘 지원되지 않습니다. Microsoft의 컴파일러를 지원하는 MPIR (www.mpir.org)이라는 GMP 포크가 있습니다.
casevh 2010

내가 참조. 즉, Python 구현은 ANSI C와 비슷하지만 GMP 구현은 __asm ​​트릭을 사용합니다. 설명해 주셔서 감사합니다.
Siu Ching Pong -Asuka Kenji- 2010

8

개인 및 상업적 사용을 위해 무료로 제공되는 작은 템플릿 헤더 전용 라이브러리 인 TTMath를 참조하십시오 .


야! 이것은 사용하기 쉬운 라이브러리이며 CPU 성능을 활용하고 C ++ 템플릿 마법을 사용하여 작업을 완료하는 것 같습니다. 훌륭한 도서관! 당신을 위해 +1!
Siu Ching Pong -Asuka Kenji- 2013

예, 그리고 그것은 허용되는 비 카피 레프트 BSD 라이센스를 가지고 있습니다.
plasmacel

위 페이지에서 : "컴파일 시간에 설정할 수있는 값의 크기입니다." -따라서 이것은 요구 사항에 맞지 않습니다.
osxdirk


4

무엇에 대한 PARI ? 최고의 GMP를 기반으로 구축되었으며 필요한 수 이론 연산 (및 많은 기호 계산 관련 항목)에 대한 다른 모든 장점을 제공합니다.


안녕 포트란 (!), 좋아 보인다! 정보 감사합니다!
Siu Ching Pong -Asuka Kenji- 2010

환영합니다 :-) 또한 Pari를 사용하면 GP를 사용하여 빠른 프로토 타입을 롤링 할 수 있으며, 최적화 된 C 버전을 작성하는 것이 만족 스러우면이를 지원하기 위해 GP-> C 컴파일러와 함께 제공됩니다.
fortran
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.