1

数値が浮動小数点表現で一方向に表現されているかどうか、より大きなサイズの表現で同じように表現されるかどうか疑問に思っています。つまり、数値が a として特定の表現を持っている場合、それがa にキャストされたfloat場合は同じ表現になり、 aにキャストされた場合も同じになります。floatdoublelong double

私は BigInteger 実装を作成していて、渡された浮動小数点数を a を受け入れる関数に送信しlong doubleて変換しているので、疑問に思っています。それが私の次の質問につながります。明らかに、浮動小数点は常に正確な表現を持っているとは限りません。std::cout << std::fixed << someFloat;渡された数値と同じでなくても、与えられた数値と同じ数値を表現しようとするのは合理的ですか?それは私が得ることができる最も正確な表現ですか? もしそうなら、 ...

その値を抽出する最良の方法は何ですか (基数は 10 の累乗)。現時点では、それを文字列として取得し、文字列コンストラクターに渡しています。これは機能しますが、もっと良い方法があると感じずにはいられませんが、基数で割ったときに剰余を取ることは浮動小数点数では正確ではありません。

最後にuintmax_t、システム上で常に最大の浮動小数点型となる型名である に相当する浮動小数点があるのか​​、それとも がlong double常に最大になるため (たとえそれがダブル)。

ありがとう、T.

4

3 に答える 3

9

「同じ表現」とは、「パディングを除いてメモリ内でまったく同じバイナリ表現」を意味する場合、いいえ。倍精度には、指数と仮数の両方のビットが多く、指数バイアスも異なります。しかし、単精度の値は倍精度で正確に表現できると思います (おそらく非正規化された値を除く)。

「浮動小数点が常に正確な表現を持っているとは限らない」と言うとき、あなたが何を意味するのかわかりません。確かに、すべての 10 進浮動小数点値が正確な 2 進浮動小数点値を持つわけではありません (その逆も同様です) が、それが問題になるかどうかはわかりません。浮動小数点入力に小数部分がない限り、適切な大きさの "BigInteger" 形式で正確に表現できるはずです。

base-10 表現による変換は、適切な方法ではありません。理論的には、必要なのは長さ 1024 までのビット配列であり、それをすべてゼロに初期化し、仮数ビットを指数値でシフトするだけです。しかし、あなたの実装についてもっと知らなければ、私が提案できることはこれ以上ありません!

于 2010-10-06T16:18:04.970 に答える
2

doubleのすべての値が含まれますfloatlong doubleのすべての値が含まれますdouble。したがって、 への変換によって値情報が失われることはありませんlong double。ただし、関連する元のタイプに関する情報が失われています (以下を参照)。

一般的な C++ セマンティクスに従うために、浮動小数点値から整数への変換では、値を丸めずに切り捨てる必要があります。

主な問題は、正確ではない大きな値です。この関数を使用してfrexp、浮動小数点値の基数 2 の指数を見つけることができます。std::numeric_limits<T>::digitsそれが正確に表現できる整数範囲内にあるかどうかを確認するために使用できます。

私の個人的な設計上の選択は、fp 値が正確に表現できる範囲内にあることを表明することです。つまり、実際の引数の範囲を制限します。

floatそれを適切に行うには、引数を取るオーバーロードが必要ですdouble。正確に表現できる範囲は、実際の引数の型に依存するからです。

fp 値が許容範囲内にある場合は、 と を使用floorfmodて、必要な数値システムの数字を抽出できます。

于 2010-10-06T18:27:37.853 に答える
0

はい、IEEE float から double、extended に移行すると、小さいフォーマットから大きいフォーマットまでのビットが表示されます。たとえば、

独身
せえええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええ
ダブル
せえええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええ

6.5 シングル
0 10000001 101000...
6.5ダブル
0 10000000001 101000...
13 シングル
0 10000010 101000...
13 ダブル
0 10000000010 101000...

仮数を残して、ゼロを追加します。

指数は右詰めで、msbit の次を符号拡張し、msbit をコピーします。

たとえば、-2 の指数。-2 から 1 を引くと、-3 になります。2 の補数の -3 は 0xFD または 0b11111101 ですが、フォーマットの指数ビットは 0b01111101 で、msbit が反転されています。また、倍精度 -2 指数の場合、-2-1 = -3 です。または 0b1111...1101 になり、それが 0b0111...1101 になり、msbit が反転します。(指数ビット = twos_complement(exponent-1)、msbit を反転)。

上記のように、指数 3 3-1 = 2 0b000...010 は、上位ビット 0b100...010 を反転します。

はい、単精度からビットを取得して、倍精度数の適切な場所にコピーできます。便利な拡張フロート参照はありませんが、同じように機能することは確かです。

于 2010-10-08T01:10:01.243 に答える