手動解析のための浮動小数点数の文字列から
-
01-07-2019 - |
質問
もちろんほとんどの言語おいて図書館機能のことをしたいのでやっている。
このfloatを与えたようにCまたはJavaプログラムを除くために"f"および"d"suffix)は、例えば"4.2e1
", ".42e2
"もしくは単に"42
".一般には、"整数部の小数点以下の小数部の小数点以下、"指数".三つの整数です。
での個人桁だ作成した値の型 float
または double
失うことなく精密?
おうと思っていを乗じた数値の整数部分と10^n, では、 n 数は小数部の桁、その小数部を整数部分を差し引い n からの眠しました。この効果が 4.2e1
入 42e0
, ります。そしてこれを利用 pow
関数計算10^指数 掛けの結果の新しい整数です。それでは、この方法で保証最大の精度を通?
意思想す。
解決
私が直接組み立ての浮動小数点数を利用バイナリ表現。
読みの数字の後、最初のすべての桁を表します。い整数演算.また、小数点の眠しました。このつが重要となる。
現在組み立てることができご浮動小数点数になります。第一については、スキャンする整数値の桁数を設定しビット(abcd).
のビットの直後に最初のビットは仮数.
の指数をいく。ご存知のビット位置が、位置、小数点以下のオプション指数からは、科学表記です。●組み合わせと追加の浮動小数点の指数のバイアス(だと思い127もチェックも参照ください).
この指数はどの範囲で0-255です。まで拡大または縮小する正又は負の無限の番号(特例)です。
店舗指数としてのビット24-30のfloat.
最も重要なビットですぐ動いちゃうな。そのための一つの手段はマイナスゼロの手段です。
すく記述する以外になっているので、分解の浮動小数点数の指数と仮数とんどのプラットフォームに対応
ちなみに浮動小数点演算そのものは悪いことで、いつでもゲストに合った働きかけの仮数を切り捨てられることから23重要なビット.ん、正確に表現することができてうれしいです。
他のヒント
その他のすべての回答によってどのよう 硬い でいます。を行うことができ初カットアプローチでこれを正確に、ある程度のものまで考慮IEEE丸めモード(et al)まったの 右 答えになります。長々と書きましたがナイーブ実装の前で大量のエラーになります。
いない場合は恐怖の数学でも、私のおすすめの以下の記事によるデビッド-ゴールドバーグ どのコンピュータ科学者にとって知っておくべきこ浮動小数点演算.く理解しよう背後にある実装では、そのビットとして存在している。
私の最高のアドバイスを作atoi実施に移行します。んの早期発見が欠落していくものだが、いくつか見る strtod'エクイティ-ファイナンスにより使用可右のパスが長い、長いパス)です。最終的にすぐの評価 挿入dietyこちら ることが標準ライブラリ.
/* use this to start your atof implementation */
/* atoi - christopher.watford@gmail.com */
/* PUBLIC DOMAIN */
long atoi(const char *value) {
unsigned long ival = 0, c, n = 1, i = 0, oval;
for( ; c = value[i]; ++i) /* chomp leading spaces */
if(!isspace(c)) break;
if(c == '-' || c == '+') { /* chomp sign */
n = (c != '-' ? n : -1);
i++;
}
while(c = value[i++]) { /* parse number */
if(!isdigit(c)) return 0;
ival = (ival * 10) + (c - '0'); /* mult/accum */
if((n > 0 && ival > LONG_MAX)
|| (n < 0 && ival > (LONG_MAX + 1UL))) {
/* report overflow/underflow */
errno = ERANGE;
return (n > 0 ? LONG_MAX : LONG_MIN);
}
}
return (n>0 ? (long)ival : -(long)ival);
}
の標準アルゴリズムへの変換には十進数、浮動小数点近似にはウィリアム-Clingerの 読み方浮動小数点数を正確に, ダウンロード可能から こちらの.ここは正しく無数の精度の整数、少なくとも一定の割合は、対応するためのコーナー。
アルゴリズムのためのものその他の方法や印刷の最小数点数から浮動小数は、ハンバーガーとDybvigの 印刷浮動小数点数を迅速かつ的確に, ダウンロード可能な こちらの.が必要である複数の精度の整数演算
参照David Mゲイの 正しく丸めたバイナリ-小数点や桁-バイナリ変換 のためのアルゴリズムの両方。
きを無視する小数点の構文解析時には除く。うに入力した:156.7834e10...これに容易に解析され、整数1567834続いてe10は、おいし変更するe6、小数点以下の桁数は4桁の終わりからの"数字"の一部が浮いてしまうからなのです。
精度が問題。する必要がありまチェックに、IEEEの仕様に言います。の場合のビット数を仮数(割合)はより大きいビット数に整数タイプ、しょうがな精度が誰かの種類は数など
5123.123123e0-に変換する5123123123当社の手法は、大きな整数、ビット5.123123123があり、仮数のfloat。
この方法を用いる各桁目の前の小数点以下の桁数増殖の現在の計(float)により10日後に追加し、新しい完了します。のための桁の数字の後に小数点以下の桁数を掛けると、桁の数字による成長力の10を追加する前に、現在の合計。この方法のようbegいると判断せざるを得ないとのやっていること、しかし、そのままを使用する必要があるの浮動小数点のプリミティブを使わずに容易に利用可能の解析。
とにかく頑張ってください。
あり, できる分解の建設への浮動小数点 どの これらの業務 正確な, できない シングル最終inexact 動作します。
残念ながら、浮動小数点 すぐ なinexactきを超える精度での仮数の結果を四捨五入で表示。回丸"エラー"が導入されている累積進事業...
なので、一般的には、 NO, 使用できなくなようなナイーブアルゴリズムを変換する任意の部で"年"、小数部で"こにつながる可能性もある不満番号により複数のulpの訂正について話します。
がどんな姿を見せてくれるだろうか遠くまで:
ご丁寧に再構築に浮かぶようになります:
if(biasedExponent >= 0)
return integerMantissa * (10^biasedExponent);
else
return integerMantissa / (10^(-biasedExponent));
があるリスクを上回る精度の両方の場合履歴の積算のintegerMantissa場合には多くの数字、および揚する場合は10のbiasedExponent...
幸い場合、最初の二つの業務を正確にできない最終inexact運は、IEEE性の結果を四捨五入。
ように単精度浮動小高い精度の24ビット.
10^8 > 2^24 > 10^7
この2の倍数ですので金額は増加する一方である指数の仮数を変更して対応力の5べき乗10:
5^11 > 2^24 > 5^10
でも、できる7桁の精度のintegerMantissa、biasedExponent間-10 10.
Double精度で、53のビット
10^16 > 2^53 > 10^15
5^23 > 2^53 > 5^22
いることができ15桁の半角数字、偏った指数と-22 22.
でご覧いただく場合は番号は常に、正しい囲---(本当に難しいので、目を手配のバランスの仮数と指数を挿入し取り付けたり取り外したりすると末尾のゼロ).
その他の店舗ではご利用延長します。
の場合を記述するためのシステムを提案任意精度の整数、それは少ないものでもなかったこのSmalltalkとbloggedまで http://smallissimo.blogspot.fr/2011/09/clarifying-and-optimizing.html や http://smallissimo.blogspot.fr/2011/09/reviewing-fraction-asfloat.html
これらは単純素朴なります。幸いなことに、libcが最適化されています。
私が最初に思いをはせる構文の文字列を int64
仮数と int
小数点の指数のみを使用し、第18桁の仮数.例えば、1.2345e-5のように解析され12345と-9.その思いを乗じた仮数10decrementing指数までの仮数18桁の長い(>56ビットの精度).そのように小数点以下の桁数指数は、表の要因であり、バイナリー指数を使用できる変数から小数n*10^mバイナリp*2^qます。のように int64
思い掛け、仮数部のようなことを得ることができたのは64ビットの128ビットの番号です。この int64
仮数にキャストできることをfloatになだけ、必要な精度の2^q指数の適用を掛け算とな損失の精度。
いることは非常に正確かつ高速にしたいことがあるもの特別番号NaN、無限大,-0.0、楽しんでいただくために。いないと考え、denormalized番号または丸めモードがある。
用することを理解する標準IEEE754るために適切なバイナリ表現。後に利用できる Float.intBitsToFloat または ダブル。longBitsToDouble.
したい場合は、最高精度の結果を、可能なものを使用できる高内部精度、そしてdownconvertの結果を望ます。大きな数ULPsのエラーを繰り返し掛け10必要に応じて、ご希望の精度。うするには、できるだけ多くの捕虜()関数にてイベントは終了いたしました。inexact績に大きな指数.
で変換することはできません任意の文字列を表す数字をダブルまたはfloatを失わないます。多くの数を正確に表現できる点など"0.1")のできない近似にバイナリのfloatまたはdouble.これは、その端数の1/3にできない正確に表現で説明できる書き込むときは0.333333...
ない場合利用については図書館機能に直接ませんのソースコードの方は図書館機能の?またJava;最JDKs船のソースコードのクラス図書館などの見どのようにjava.lang.ダブル。parseDouble(String)メソッドです。もちろんのようなものBigDecimalがより良い制御精度と丸めモードがとうござい"であることが必要でfloatまたはdouble.
使用状態です。かなりやすいものを作る場合は、データストリームが中断るためには、ただひたすらいの状態の部分的な結果が出ています。利用できるパーサジェネレータ(だいようにすることができます。
い末端である。状態機械のこのタスクとして多くのみなパーサできます。私は一つの作品を作るのに、と思うのですが完了していると思い13。
その問題点を合わせるようにします。
私はハードウェア-エンジニアの関心設計の浮動小数点ハードウェア私は私の第二の実装です。
そして今日 http://speleotrove.com/decimal/decarith.pdf
るのは18ページをつかの興味深い試験である。
り合いをつけて暮らしてきたわけでClingerの記事が単純なハードウェアエンジニア、ありがとうございます心のコードを示した。への参照ィのアルゴリズムとしてasnweredにKnuthのテキストです。入力と出力の両方には問題がある。
全ての参照は様々な記事は素晴らしいものがあります。
っていない会員のご登録はこちらからでない場合は、ログインを取り消されるかもしれませんでbroh.(broh-dot).
クライドオーディトリアム