任意精度の算術演算をサポートするプログラミング言語は何ですか?また、任意の桁数を出力する方法の簡単な例を挙げていただけますか?
18 に答える
一部の言語には、このサポートが組み込まれています。たとえば、Java のjava.math.BigDecimalや Python のdecimal.Decimalを見てください。
他の言語には、この機能を提供するライブラリが用意されていることがよくあります。たとえば、C ではGMPやその他のオプションを使用できます。
この記事の「任意精度ソフトウェア」セクションでは、オプションの概要を説明しています。
マテマティカ。
N[Pi, 100]
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068
Mathematica は任意の精度を持っているだけでなく、デフォルトで無限の精度を持っています。1/3 のようなものを有理数として保持し、Sqrt[2] のようなものを含む式でさえも、数値の近似値を要求するまでシンボリックに保持します。これは、任意の小数点以下の桁数にすることができます。
Smalltalk は最初から任意精度の整数と分数をサポートしています。gnu Smalltalk の実装は内部で GMP を使用していることに注意してください。また、さまざまな方言 (Squeak/Pharo Visualworks および Dolphin) 用に ArbitraryPrecisionFloat を開発しています。http: //www.squeaksource.com/ArbitraryPrecisionFl.html を参照してください。
Common Lisp では、
(format t "~D~%" (expt 7 77))
printf 形式の "~D~%" は "%d\n" になります。任意精度演算は Common Lisp に組み込まれています。
Pythonにはそのような機能があります。ここに優れた例があります。
記事から:
from math import log as _flog
from decimal import getcontext, Decimal
def log(x):
if x < 0:
return Decimal("NaN")
if x == 0:
return Decimal("-inf")
getcontext().prec += 3
eps = Decimal("10")**(-getcontext().prec+2)
# A good initial estimate is needed
r = Decimal(repr(_flog(float(x))))
while 1:
r2 = r - 1 + x/exp(r)
if abs(r2-r) < eps:
break
else:
r = r2
getcontext().prec -= 3
return +r
また、python クイック スタート チュートリアルでは、任意の精度について説明しています: http://docs.python.org/lib/decimal-tutorial.html
getcontext について説明します。
getcontext() 関数は現在のコンテキストにアクセスし、設定を変更できるようにします。
編集: getcontext に関する説明を追加しました。
多くの人が Python の decimal モジュールを推奨しましたが、深刻な数値の使用には decimal よりもmpmathを使用することをお勧めします。
コボル
77 VALUE PIC S9(4)V9(4).
符号付き変数ウィッチ 4 小数点。
PL/1
DCL VALUE DEC FIXED (4,4);
:-) 他の古いものは思い出せません...
冗談はさておき、私の例が示すように、単一の機能に基づいてプログラミング言語を選択するべきではないと思います。事実上すべてのまともな最近の言語は、いくつかの専用クラスで固定精度をサポートしています。
スキーム(lispのバリエーション)には、「bignum」と呼ばれる機能があります。フル言語環境と埋め込み可能なスクリプトオプションの両方で利用できる多くの優れたスキーム実装があります。私が保証できるいくつか
MitScheme(gnuスキームとも呼ばれます)PLTScheme Chezscheme Guile(gnuプロジェクトとも呼ばれます)Scheme 48
PHP には BCMath があります。dll をロードしたり、モジュールをコンパイルしたりする必要はありません。文字列として表される任意のサイズと精度の数値をサポート
<?php
$a = '1.234';
$b = '5';
echo bcadd($a, $b); // 6
echo bcadd($a, $b, 4); // 6.2340
?>
Ruby の整数と浮動小数点数 (数学的に言えば有理数) は、既定では、従来の CPU 関連の制限に厳密には結び付けられていません。Ruby では、サイズが従来のサイズの最大値を超えた場合、integer と float は自動的に透過的にいくつかの「bignum 型」に切り替えられます。
おそらく、「bignums」を使用する、合理的に最適化された「完全な」多種多様な数学ライブラリを使用したいと思うでしょう。これは、Mathematica ライクなソフトウェアが真にその機能を発揮するところです。
2011年現在、Mathematica は非常に高価であり、特に数学ソフトウェアを小規模で低価格のWebアプリケーションまたはオープンソースプロジェクトのコンポーネントとして出荷したい場合、ハッキングや再出荷の観点から非常に制限されています. ビジュアライゼーションが不要な生の数値演算のみを行う必要がある場合、Mathematica と Maple に代わる非常に実行可能な代替手段が存在します。代替手段は REDUCE Computer Algebra System です。これは Lisp ベースのオープン ソースであり、成熟しており (数十年)、活発に開発されています (2011 年)。Mathematica と同様に、REDUCE は記号計算を使用します。
Mathematica の評価については、2011 年の時点で Mathematica がインタラクティブな視覚化で最も優れているように思われますが、プログラミングの観点からは、たとえ Mathematica がオープン ソース プロジェクトであったとしても、より便利な代替手段があると思います。私には、Mahtematica も少し遅く、巨大なデータ セットの操作には適していないように思えます。Mathematica のニッチは理論的な数学であり、実際の数値計算ではないように私には思えます。一方、Mathematica の発行者である Wolfram Research は、地球上で最も高品質ではないにしても、最も高品質で無料で使用できる数学リファレンス サイトの 1 つ、http://mathworld をホストおよび維持しています。 wolfram.com/ Mathematica にバンドルされているオンライン ドキュメンテーション システムも非常に優れています。
速度について話すときは、REDUCE が Linux ルーター上でも動作すると言われていることに言及する価値があります。REDUCE 自体は Lisp で書かれていますが、2 つの固有の Lisp 実装が付属しています。Lisp の 1 つは Java で実装され、もう 1 つは C で実装されています。少なくとも数学の観点からは、どちらも適切に機能します。REDUCE には 2 つのモードがあります。伝統的な「数学モード」と、REDUCE が自己記述している言語である Lisp によって内部のすべてに完全にアクセスできる「プログラマー モード」です。
したがって、私の意見では、数学ルーチンを作成するのに必要な作業量を見ると、REDUCE ですべてが成熟しているすべての記号計算は言うまでもなく、膨大な量の時間を節約できるということです (文字通り、数十年) ) 数学の部分のほとんどを REDUCE で実行することによって、特にプロの数学者によって長期間にわたってテストおよびデバッグされ、実際の専門的なタスクのために旧式のスーパーコンピューターで記号計算を実行するために使用され、素晴らしく、本当に高速に動作することを考えると、 、最新のローエンド コンピューターで。ここで名前を挙げたくない少なくとも 1 つの商用パッケージとは異なり、クラッシュしたこともありません。
http://www.reduce-algebra.com/
シンボリック計算が実際に不可欠な場合を説明するために、逆行列によって連立一次方程式を解く例を示します。行列を反転するには、行列式を見つける必要があります。CPU が直接サポートする浮動小数点型で行われる丸めは、理論的には逆数を持つ行列を、逆数を持たない行列にレンダリングできます。これにより、ほとんどの場合、ソフトウェアは問題なく動作する可能性がありますが、データが少し「不運」である場合、丸め以外にアルゴリズム的にソフトウェアに問題がないにもかかわらず、アプリケーションがクラッシュする状況が発生します。浮動小数点数の。
絶対精度の有理数には重大な制限があります。より多くの計算が実行されるほど、より多くのメモリが消費されます。2011年の時点で、その問題の解決策はわかりませんが、注意して数値で実行された操作の数を追跡し、数値を丸めてメモリを節約する以外に、次のように丸めを行う必要があります前述の問題を回避するための計算の非常に正確な段階。可能であれば、丸めは計算の最後で最後の操作として実行する必要があります。
任意精度の演算を処理する Javascript ライブラリがいくつかあります。
たとえば、私のbig.jsライブラリを使用すると、次のようになります。
Big.DP = 20; // Decimal Places
var pi = Big(355).div(113)
console.log( pi.toString() ); // '3.14159292035398230088'
R では、Rmpfrパッケージを使用できます。
library(Rmpfr)
exp(mpfr(1, 120))
## 1 'mpfr' number of precision 120 bits
## [1] 2.7182818284590452353602874713526624979
ここでビネットを見つけることができます: R を使用した任意の正確な計算: Rmpfr パッケージ
バージョン 8.5 から、LibTomMath の厚意により、Tcl にもそれらが含まれているようです。
http://wiki.tcl.tk/5193 http://www.tcl.tk/cgi-bin/tct/tip/237.html http://math.libtomcrypt.com/
Java は BigDecimal で bignum 操作をネイティブに実行できます。GMPは、C/C++ を使用した bignum の事実上の標準ライブラリです。
.NET の世界で作業したい場合は、引き続き java.math.BigDecimal クラスを使用できます。(フレームワークで) vjslib への参照を追加するだけで、Java クラスを使用できます。
素晴らしい点は、それらが任意の .NET 言語から使用できることです。たとえば、C# の場合:
using java.math;
namespace MyNamespace
{
class Program
{
static void Main(string[] args)
{
BigDecimal bd = new BigDecimal("12345678901234567890.1234567890123456789");
Console.WriteLine(bd.ToString());
}
}
}