10進数を2進数で正確に表現できないのはなぜですか?


284

浮動小数点表現についてSOに投稿された質問がいくつかあります。たとえば、10進数0.1には正確な2進数表現がないため、==演算子を使用して別の浮動小数点数と比較するのは危険です。浮動小数点表現の背後にある原理を理解しています。

私が理解していないのは、数学的な観点から、小数点の右側の数値が左側の数値よりも「特別」である理由です。

たとえば、61.0という数値は、任意の数値の整数部分が常に正確であるため、正確なバイナリ表現になります。しかし、6.10という数値は正確ではありません。私がしたことは、小数点を1桁移動することだけでしたが、突然、ExactopiaからInexactvilleに移動しました。数学的には、2つの数値の間に本質的な違いがあってはなりません。それらは単なる数値です。

それとは対照的に、小数部を反対方向に1桁動かして610を生成しても、Exactopiaのままです。私はその方向(6100、610000000、610000000000000)に進むことができますが、それらはまだ正確です。ただし、小数がしきい値を超えるとすぐに、数値は正確ではなくなります。

どうしたの?

編集:明確にするために、IEEEなどの業界標準の表現についての議論は避け、数学的に「純粋な」方法であると私が信じるものに固執したいと思います。基数10では、位置の値は次のとおりです。

... 1000  100   10    1   1/10  1/100 ...

バイナリでは、次のようになります。

... 8    4    2    1    1/2  1/4  1/8 ...

また、これらの数に任意の制限はありません。位置は左と右に無制限に増加します。


2
これは、浮動小数点数の内部で何が起こっているかを正確に理解するのに役立ちます:浮動小数点数の構造
ジョンD.クック

57
バイナリでは、数値3は2¹+ 2°= 2 + 1として表されます。簡単です。では、1/3を見てください。2の負の累乗を使用して、それをどのように表現しますか?少し実験すると、1/3が無限シーケンス2 ^ -2 + 2 ^ -4 + 2 ^ -6 + 2 ^ -8 + ...の合計に等しいことがわかります。バイナリで正確に表現するのは簡単ではありません。
Lars Haugseth、2009

21
ジョン・スキートはあなたの体の質問にとてもよく答えます。不足していることの1つは、実際には2つの異なる質問をすることです。タイトルの質問は、「10進数を2進数で正確に表現できないのはなぜですか」です。答えは、可能です。タイトルと本文の間で、「バイナリ」の考え方と「浮動小数点表現」の考え方を融合させます。浮動小数点は、精度を犠牲にして、固定数の2進数で10進数を表現する方法です。Binaryは、カウントの別のベースであり、桁数が無限であれば、Decimal Canをいくつでも表現できます。
Chris Blackwell、

3
正確な10進数表現を持つシステムがいくつかあります。それはあなたが説明するのとほとんど同じように機能します。SQLの10進数型は1つの例です。LISP言語にはそれが組み込まれています。正確な10進数計算を使用するための商用およびオープンソースライブラリがいくつかあります。これはハードウェアサポートがないというだけのことであり、そこにあるほとんどの言語とハードウェアは、32ビットまたは64ビットで無限の数を表すためのIEEE標準を実装しています。
番号

1
それはおよそ数学(それは、関連する数学のプログラミングだとしても)で、上の方が良いだろうので、この質問は、オフトピックのように見える数学
コール・ジョンソン

回答:


360

十分なスペースがあれば、10進数正確に表すことできます。浮動小数点の2進数でありません。浮動小数点タイプ(System.Decimal.NETなど)を使用する場合、2進浮動小数点で正確に表現できない多くの値を正確に表現できます。

別の見方をしてみましょう。使いやすいと思われる10進法では、1/3を正確に表現できません。0.3333333 ...(繰り返し)です。0.1を2進浮動小数点数として表すことができない理由は、まったく同じ理由です。3、9、27を正確に表すことができますが、1 / 3、1 / 9、1 / 27はできません。

問題は、3が10の因数ではない素数であることです。これは、数値に3 を掛けるときに問題になりません。問題が発生することなく、常に整数を掛けることができます。しかし、素数であり、ベースの要素ではない数値で除算すると、問題が発生する可能性があります(1をその数値で除算しようとすると、問題が発生します)。

0.1は通常、2進浮動小数点で正確に表現できない正確な10進数の最も単純な例として使用されますが、おそらく0.2は1/5であるため、より単純な例であり、5は10進数と2進数の間に問題を引き起こす素数です。


有限表現の問題に対処するための付記:

一部の浮動小数点型は、「任意に大きい」System.Decimalなど他の固定小数点サイズと同じですがjava.math.BigDecimal、システムメモリであろうと、配列の理論上の最大サイズであろうと、ある時点で制限に達します。ただし、これはこの回答の主なものとはまったく別のポイントです。本当に任意の数のビットを操作していても、浮動小数点の2進数表現で10進数の0.1を正確に表すことはできません。それを逆の方法と比較します。任意の数の10進数を指定すると、浮動2進小数点として正確に表現可能な任意の数を正確に表すことができます。


8
それはいまいましい素晴らしい例です!
トムリッター

5
...これを2回賛成できるといいのですが。私はこれについて完全に何度も尋ねられました。それは、人々がベース10の外では考えられないようなものです。へへ
ジャスティンニースナー2009

38
ええ、世界には10種類の人がいます-バイナリを理解する人と理解しない人。
duffymo 2009

83
@JonSkeet:Ctrl + Alt + Deleteは2本の指だけでは不自然に見えます。
Lars Haugseth、2009

20
@muusbolla:いいえ。10進表記1と10進表記0.9...(小数点9の後に無限に繰り返されるs)で表される数は同じです。おそらくこれを確認する最も簡単な方法は次のとおりです。x =とし0.9...ます。ご注意ください10x = 9.9....。したがって、9x = 10x - x = 9.9... - 0.9... = 9そのように9x = 9してx = 1。これを確認する方法は他にもありますが、これが最も簡単だと思います。
ジェイソン

25

たとえば、61.0という数値は、任意の数値の整数部分が常に正確であるため、正確なバイナリ表現になります。しかし、6.10という数値は正確ではありません。私がしたことは、小数点を1桁移動することだけでしたが、突然、ExactopiaからInexactvilleに移動しました。数学的には、2つの数値の間に本質的な違いがあってはなりませんこれらは単なる数値です。

10と2の基数の詳細から少し離れてみましょう。baseでb、どの数に終端の表現があり、何の数にないのですか?一瞬の思考は、整数がそのような整数が存在する場合に限り、数値xには終了b表現があることを示しています。nx b^n

ですから、例えば、x = 11/500私たちが選ぶことができるので、終端10-表現を持ってn = 3、その後とx b^n = 22、整数を。ただし、x = 1/3そうではありません。nを選択しても、3を取り除くことができないためです。

この第二の例のプロンプトたちは要因について考え、そして私たちは、いずれかのことを見ることができる合理的な x = p/q、我々はプライムfactorisationsを比較することによって、質問に答えることができます(最低条件であると仮定)bqqの素因数分解にない素因数がある場合b、適切なものを見つけることはできませんn、これらの要因を取り除くのにを。

したがって、ベース10の場合、任意の p/q場所q終端表現を持っていない2又は5以外の素因数を有します。

したがって、基数10と2に戻ると、終了10表現の有理数は、素因数分解でとs のみが存在するp/q場合の形式になります。そして、その同じ数は、が素因数分解でs のみである場合、正確に終了2表現を持ちます。q25q2

しかし、これらのケースの1つは他のサブセットです!いつでも

q2素因数分解にはs しかない

それは明らかであるにも本当のこと

q素因数分解に2sと5s しかない

または、別の言い方をすると、終了2表現がある場合常に、終了10表現がありp/qp/qます。ただし、逆は成り立たない - q素因数分解に5が含まれる場合は常に、終了10の表現を持つが、終了2の表現はない。これは、0.1他の回答で言及されている例です。

だから私たちはあなたの質問への答えを持っている- 2の素因数は10の素因数のサブセットであるため、すべて2終端番号は10終端の数字ですが、その逆はありません。6.1対6.1ではなく、約10対2です。

クロージング注意点としては、ベース5を使用(例えば)ベース17しかし、我々のコンピュータ使用されているいくつかのいたずらの人々による場合は、あなたの直感は、これで道に迷っを主導されていないだろう-はないだろう何の終了(非ゼロ、非整数)の数値両方の場合において!


では、なぜ「alert(0.15 * 0.15)」は「0.0225」を表示するのでしょうか。
Michael Geiser 2014年

5
@MichaelGeiserの短い回答:表示ポイントでの丸め。あなたが思うのは0.15、実際には(IEEE doubleとして格納されている場合) `0.149999999999999994448884876874`です。jsfiddleを参照してください。
AakashM 2014年

ポイントコードの例がわかりやすい!私はあなたにその賛成票をあげることができればいいのに!切り捨てが発生する場所を調べるには、いくつかの機能を試してみる必要があります。実際にこのゴミを処理しなければならないことに、私はまだ驚いています。人々は基本10で作業する時間のほぼ100%と非整数を使用することが多いため、浮動小数点演算のデフォルトの実装ではこの無意味なことが処理されると考えられます。
Michael Geiser、2014年

1
@MichaelGeiserベース2で動作する回路は、ベース10で動作する回路よりも小さく、高速で、電力効率が優れています。今日、オーバーヘッドを正当化できるかもしれませんが、標準が設定されていた1970年代には、大したこと。プロセッサ回路を直接サポートせずにそれを行おうとすることはさらに悪いことですが、速度には桁違いの違いがあると予想されます。
Mark Ransom

この答えはジョン・スキート自身よりもよく説明されています!
goelakash 2016年

16

根本的な(数学的な)理由は、整数を扱う場合、それらは数え切れないほど無限であることです。

つまり、それらの数は無限にありますが、シーケンス内のすべての項目をスキップせずに「数える」ことができます。つまり、アイテムを610000000000000、リストのth番目の位置にある、数式を使用してそれを計算できます。

ただし、実数は数え切れないほど無限です。「ポジションの実数を教えて」と言っ610000000000000て答えを返すことはできません。理由は、理由さえ間01あなたは浮動小数点値を検討しているとき、値の無限の数が、あります。同じことが2つの浮動小数点数にも当てはまります。

より詳しい情報:

http://en.wikipedia.org/wiki/Countable_set

http://en.wikipedia.org/wiki/Uncountable_set

更新: 申し訳ありません。質問を誤解しているようです。私の答えは、私たちがすべての現実を表現できない理由についてです値をです。浮動小数点が自動的に有理数として分類されることに気づきませんでした。


6
実際、有理数数え切れないほど無限です。しかし、すべての実数が有理数であるとは限りません。私は確かに正確な10進数のシーケンスを生成できます。これは、最終的に与えたい正確な10進数に到達します。無理な数に対処する必要がある場合でさえ、数え切れないほどの無限集合に入るのです。
Jon Skeet、

確かに、「浮動小数点」ではなく「実数」と言っているはずです。明確になります。
TM。

1
その時点で、ロジックの適用性が低下します。IMO- 2進浮動小数点を使用してすべての実数を処理できるだけでなく、すべての有理数(0.1など)も処理できないためです。言い換えれば、それは実際に可算性とはまったく関係がないと思います:)
Jon Skeet

@jonskeetジョンスキートに同意しないと自然の基本法則が破られることはわかっているので、もちろんそれはしません:)しかし、数字の内部表現を、外部で表現する値のセット。この考え方で、インデックスのリストがどれほど大きくても(たとえ無限ビットの精度であって)、実際の数値をすべて表すことはできません。
TM。

3
@TM:しかし、OPはすべての実数を表すことを試みていません。彼はすべての正確な10進数を表現しようとしています。これは有理数のサブセットであり、したがって無限に無限です。彼が無限小数のビットを10進浮動小数点型として使用している場合は、問題ありません。これらのビットを2進浮動小数点型として使用しているため、10進数で問題が発生します。
Jon Skeet、

10

スキート氏へのコメントで私が言ったことを繰り返すために: 、1 / 3、1 / 9、1 / 27、または任意の有理数を10進表記で表すができます。それには、シンボルを追加します。たとえば、数値の10進展開で繰り返される数字の上の線。2進数のシーケンスとして10進数を表す必要があるのは、1)2進数のシーケンス、2)基数ポイント、3)シーケンスの繰り返し部分を示す他の記号です。

Hehnerの引用表記は、これを行う1つの方法です。彼は引用記号を使用して、シーケンスの繰り返し部分を表します。記事:http : //www.cs.toronto.edu/~hehner/ratno.pdfおよびWikipediaのエントリ:http : //en.wikipedia.org/wiki/Quote_notation

表現システムにシンボルを追加できないと言っていることは何もないので、バイナリ引用符表記を使用して10進数の有理数を正確に表すことができます。逆も同様です。


サイクルがどこで始まりどこで終わるかがわかっていれば、その表記法は機能します。人間はサイクルの検出にかなり優れています。しかし、一般的に、コンピューターはそうではありません。繰り返し記号を効果的に使用できるようにするには、計算を実行した後、コンピューターがサイクルの位置を把握できる必要があります。たとえば、数値が1/3の場合、サイクルはすぐに始まります。しかし、数値1/97の場合、少なくとも96桁の答えを解くまで、サイクルは表示されません。(実際には、96 * 2 + 1 = 193桁が必要です。)
Barry Brown

4
実際、コンピュータがサイクルを検出することはまったく難しいことではありません。Hehnerの論文を読むと、さまざまな算術演算のサイクルを検出する方法が説明されています。たとえば、繰り返し減算を使用する除算アルゴリズムでは、以前に見た違いが見られるときにサイクルがどこから始まるかがわかります。
ntownsend 2009

3
また、問題は数値を正確に表すことでした。時々正確な表現は多くのビットを意味します。引用表記の優れた点は、Hehnerが、標準の32ビット固定長表現と比較して、表現のサイズを平均で31%節約できることを示していることです。
ntownsend 2009

6

BCD- Binary-coded Decimal-表現は正確です。スペース効率はそれほど高くありませんが、この場合、精度を上げるためにトレードオフになります。


1
BCDは、他のどのベースよりも正確ではありません。例:BCDで1/3を正確に表すにはどうすればよいですか?できません。
イェルクWミッターク

12
BCDはDECIMALの正確な表現であり、そのため、その名前の「10進数」の部分です。1/3の正確な10進表記もありません。
アラン

4

これは、1/3を10進数で正確に表すことができないのと同じ理由です。0.33333(3)と言う必要があります。バイナリでは、同じタイプの問題ですが、数値の異なるセットで発生します。


4

(注:ここでは2進数を示すために「b」を追加します。他のすべての数値は10進数で示されます)

物事を考える1つの方法は、科学表記法のようなものです。私たちは、6.022141 * 10 ^ 23のような科学表記法で表された数値を見るのに慣れています。浮動小数点数は、仮数と指数の類似の形式を使用して内部的に格納されますが、10の代わりに2のべき乗を使用します。

61.0は、仮数と指数を使用して1.90625 * 2 ^ 5または1.11101b * 2 ^ 101bに書き換えることができます。これに10を掛けて(小数点を移動)するには、次のようにします。

(1.90625 * 2 ^ 5)*(1.25 * 2 ^ 3)=(2.3828125 * 2 ^ 8)=(1.19140625 * 2 ^ 9)

またはバイナリの仮数と指数と一緒に:

(1.11101b * 2 ^ 101b)*(1.01b * 2 ^ 11b)=(10.0110001b * 2 ^ 1000b)=(1.00110001b * 2 ^ 1001b)

数値を乗算するためにここで行ったことに注意してください。仮数を乗算し、指数を追加しました。次に、仮数部が2より大きく終わったので、指数をバンプして結果を正規化しました。これは、10進数の科学表記で数値の演算を実行した後に指数を調整する場合と同じです。どちらの場合も、使用した値はバイナリで有限表現されていたため、基本的な乗算および加算演算によって出力された値も有限表現の値を生成しました。

ここで、61を10で除算する方法を考えてみましょう。まず、仮数1.90625と1.25を除算します。10進数では、これは1.525といい、短い数字です。しかし、バイナリに変換するとどうなるでしょうか。通常の方法で行います。整数の10進数を2進数に変換するのと同じように、可能な限り最大の2の累乗を差し引きますが、2の負の累乗を使用します。

1.525-1 * 2 ^ 0-> 1
0.525-1 * 2 ^ -1-> 1
0.025-0 * 2 ^ -2-> 0
0.025-0 * 2 ^ -3-> 0
0.025-0 * 2 ^ -4-> 0
0.025-0 * 2 ^ -5-> 0
0.025-1 * 2 ^ -6-> 1
0.009375-1 * 2 ^ -7-> 1
0.0015625-0 * 2 ^ -8-> 0
0.0015625-0 * 2 ^ -9-> 0
0.0015625-1 * 2 ^ -10-> 1
0.0005859375-1 * 2 ^ -11-> 1
0.00009765625 ...

ええとああ。今、私たちは困っています。1.90625 / 1.25 = 1.525は、2進数で表現すると繰り返し分数であることがわかります。そして、特定のポイントを超えてゼロを仮定します。61を10で割ったときに表示されるエラーは、次の違いです。

1.100001100110011001100110011001100110011 ... b * 2 ^ 10b
そして、例えば:
1.100001100110011001100100110b * 2 ^ 10b

浮動小数点値に関連する精度の損失につながるのは、仮数のこの丸めです。仮数が正確に表現できる場合でも(たとえば、2つの数値を加算するだけの場合)、仮数が桁数が多すぎて指数を正規化した後に収まらない場合は、数値が失われる可能性があります。

10進数を扱いやすいサイズに丸め、最初の数桁だけを指定するときは、常にこのようなことをしています。結果を10進数で表現するので、自然に感じます。しかし、小数を四捨五入してから別の基数に変換すると、浮動小数点の四捨五入により、小数と同じくらい醜く見えます。


4

これは良い質問です。

あなたの質問はすべて「数値をどのように表すのですか?」に基づいています。

すべての数値は、10進表記または2進(2の補数)表記で表すことができます。それらすべて!!

BUT一部(それらのほとんどは)(小数表現のための「9」から「0」又はバイナリ位置のための「1」または「0」、「1」)の要素の無限数を必要とします。

10進数表現の1/3のように(1/3 = 0.3333333 ... <-無限数の「3」)

バイナリの0.1のように(0.1 = 0.00011001100110011 .... <-無限の "0011"を使用)

すべてがそのコンセプトの中にあります。お使いのコンピューターは有限の数字のセット(10進数または2進数)しか考慮できないため、コンピューターで正確に表現できるのは一部の数値のみです...

そしてジョンが言ったように、3は10の因数ではない素数なので、1/3は10を底とする有限数の要素で表すことはできません。

61を表すことはできますが、任意精度の算術を使用しても、基数2の番号付け位置システムは6.1を完全に記述することはできません。

6.1の場合、別の表現(10進表現、または浮動小数点値の表現に基数2または基数10を許可するIEEE 854など)を使用する必要があります。


1/3を小数自体として表すことができます。それを表現するのに無限のビット数は必要ありません。1を取り、それを3で割った結果ではなく、単に1/3として表すだけです。いくつかのシステムがそのように機能します。次に、標準の/ * +-および同様の演算子を使用して分数の表現を操作する方法が必要ですが、それは非常に簡単です。ペンと紙でこれらの操作を実行でき、コンピューターにそれを実行するように指示することは大したことではありません。
nos

「バイナリ(2の補数)表現」について話していました。もちろん、他の表現を使用すると、有限数の要素でいくつかの数を表現するのに役立つ場合があります(他のいくつかには無限数の要素が必要になります)
ThibThib

3

浮動小数点で十分な数を作成すると(指数を実行できるため)、小数点の前でも不正確になります。したがって、前提が間違っているため、あなたの質問が完全に有効であるとは思いません。浮動小数点数はある時点で指数を使用して数の大きさを表す必要があり、同様にある程度の精度が失われるため、10だけシフトしても常に精度が高くなるとは限りません。


3

まだ誰もこれを述べていないことに驚いています。継続分数を使用してください。このように、有理数は2進数で有限に表すことができます。

いくつかの例:

1/3(0.3333 ...)

0; 3

5/9(0.5555 ...)

0; 1, 1, 4

10/43(0.232558139534883720930 ...)

0; 4, 3, 3

9093/18478(0.49209871198181621387596060179673 ...)

0; 2, 31, 7, 8, 5

ここから、整数のシーケンスをメモリに格納するさまざまな既知の方法があります。

完全な精度で数値を保存することに加えて、継続分数には、最良の有理近似など、他のいくつかの利点もあります。連続する小数部の数値のシーケンスを早期に終了することを決定した場合、残りの数字(小数部に再結合した場合)が可能な限り最高の小数部を提供します。これは、piの近似値を見つける方法です。

Piの継続部分:

3; 7, 15, 1, 292 ...

シーケンスを1で終了すると、端数が得られます。

355/113

これは優れた有理近似です。


しかし、それをバイナリでどのように表現しますか?たとえば、15を表すには4ビットが必要ですが、292には9が必要です。ハードウェア(またはソフトウェア)は、ビット境界がそれぞれの間にある場所をどのようにして知るのでしょうか。これは、効率と精度のトレードオフです。
2013

2

方程式で

2^x = y ;  
x = log(y) / log(2)

したがって、次のようなバイナリの対数ベースシステムを作成できるかどうか考えていました。

 2^1, 2^0, 2^(log(1/2) / log(2)), 2^(log(1/4) / log(2)), 2^(log(1/8) / log(2)),2^(log(1/16) / log(2)) ........

これで問題を解決できる可能性があるため、32.41のようなものをバイナリで記述したい場合は、

2^5 + 2^(log(0.4) / log(2)) + 2^(log(0.01) / log(2))

または

2^5 + 2^(log(0.41) / log(2))

1

問題は、数値が実際に正確に61.0であるかどうかを本当に知らないことです。このことを考慮:


float a = 60;
float b = 0.1;
float c = a + b * 10;

cの値は何ですか?.1には正確なバイナリ表現がないため、bは実際には.1ではないため、正確には61ではありません。


1

数字の意味が整数から非整数に変わったため、しきい値があります。61を表すには、6 * 10 ^ 1 + 1 * 10 ^ 0になります。10 ^ 1と10 ^ 0はどちらも整数です。6.1は6 * 10 ^ 0 + 1 * 10 ^ -1ですが、10 ^ -1は1/10であり、整数ではありません。それはあなたがInexactvilleに行く方法です。


1

パラレルは、分数と整数で構成できます。1/7などの一部の分数は、多くの小数部なしでは10進形式で表すことができません。浮動小数点はバイナリベースであるため、特殊なケースが変わりますが、同じ種類の精度の問題が発生します。


0

有理数の数は無限であり、それらを表すビットの数は有限です。http://en.wikipedia.org/wiki/Floating_point#Accuracy_problemsを参照してください


あなたが浮い使用した場合でも、偶数ビットの数が無限で、バイナリポイントを、あなたはまだあなたが偶数ビットの無限の数の小数で正確に1/3を表すことができないと同じように、正確に0.1を表現することはできません。
Jon Skeet、

3
@ジョンそれは真実ではありません:小数の数が無限であるため、たとえば「1/3」を正確に表すことができます。実際の問題は、「無限数」の小数またはビットを持つことは物理的に不可能であるということです。
ChrisW 2009

0

実際、61.0という数値には正確な浮動小数点演算がありますが、すべての整数に当てはまるわけではありません。倍精度浮動小数点数と64ビット整数の両方に1を追加するループを記述した場合、64ビット整数が完全に数値を表すポイントに到達しますが、浮動小数点はそうではありません—十分な有効ビットがないためです。

小数点の右側の近似点に到達する方がはるかに簡単です。すべての数値を2進浮動小数点で書き始めたら、それはもっと理にかなっています。

別の考え方として、61.0は10を基数として完全に表現可能であり、小数点をシフトしてもそれが変わらないことに気付いた場合、10の累乗(10 ^ 1、10 ^ -1)を乗算していることになります。 )。浮動小数点では、2の累乗を掛けても数値の精度には影響しません。完全に正確な数値がその正確な表現をどのように失うかを示すために、61.0を取り、それを3で繰り返し除算してみてください。


0

あなたは正しい整数を知っていますか?各ビットは2 ^ nを表します


2 ^ 4 = 16
2 ^ 3 = 8
2 ^ 2 = 4
2 ^ 1 = 2
2 ^ 0 = 1

浮動小数点の場合も同じです(いくつかの違いがあります)が、ビットは2 ^ -n 2 ^ -1 = 1/2 = 0.5
2 ^ -2 = 1 /(2 * 2)= 0.25
2 ^ -3 = 0.125を表します
2 ^ -4 = 0.0625

浮動小数点バイナリ表現:

指数部の符号(分数に目に見えない1が追加されていると思います)
B11 B10 B9 B8 B7 B6 B5 B4 B3 B2 B1 B0


0

上記の高得点の答えはそれを釘付けにしました。

最初にあなたの質問で底2と底10を混ぜていました、それから底に割り切れない数字を右側に置くと問題が発生します。3が10の累乗にならないため、または2の1/5が2の累乗にならないため、10進数の1/3と同様です。

ただし、浮動小数点数と等しいピリオドは使用しないでください。それが正確な表現であっても、いくつかの浮動小数点システムには複数の方法で正確に表現できるいくつかの数値があります(IEEEはこれについて悪いことですが、最初は恐ろしい浮動小数点仕様なので、頭痛が予想されます)。ここで違いはありません1/3は、計算機の数値0.3333333と等しくありません。小数点の右側に3がいくつあっても関係ありません。それは十分に近いか、または近い可能性がありますが、等しくはありません。したがって、丸め方によっては、2 * 1/3のようなものが2/3に等しくないと予想されます。浮動小数点と等しいを使用しないでください。


0

これまで説明してきたように、浮動小数点演算では、10進0.1を2進数で完全に表すことはできません。

浮動小数点および整数表現は、表される数値のグリッドまたはラティスを提供します。演算が完了すると、結果はグリッドから外れ、丸めによってグリッドに戻す必要があります。例は、バイナリグリッドの1/10です。

紳士が提案したように2進化10進数表現を使用すると、グリッド上に数値を保持できるでしょうか?


1
確かに10進数です。しかし、それは定義によるものです。1/3を10進数で表すことはできず、0.1を2進数で表すことはできません。量子化スキームは、無限に大きい数のセットに対して失敗します。
カイロタン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.