3

IEE754(64ビット)浮動小数点は、内部表現に17桁ありますが、15桁の有効数字を正しく表すことになっています。16桁目と17桁目を強制的にゼロにする方法はありますか?

参照: http ://msdn.microsoft.com/en-us/library/system.double (VS.80).aspx:。

浮動小数点数は10進数にしか近似できないこと、および浮動小数点数の精度によって、その数値が10進数に近似する精度が決まることに注意してください。デフォルトでは、Double値には10進数の15桁の精度が含まれますが、内部では最大17桁が維持されます。浮動小数点数の精度には、いくつかの結果があります。。

例番号:d1 = 97842111437.390091
d2 = 97842111437.390076
d1とd2は、小数点以下16桁と17桁が異なり、重要ではないと思われます。それらをゼロにする方法を探しています。つまり、d1 = 97842111437.390000 d2 = 97842111437.390000

4

5 に答える 5

13

反例: 有理数に最も近い 2 つの浮動小数点数

1.11111111111118

(小数点以下 15 桁) は

1.1111111111111799942818834097124636173248291015625
1.1111111111111802163264883347437717020511627197265625

つまり、 で始まる浮動小数点数はありません1.1111111111111800

于 2009-10-05T18:10:19.137 に答える
3

この質問は少し形式が正しくありません。ハードウェアは数値を 10 進数ではなく 2 進数で格納します。したがって、一般的なケースでは、基数 10 で正確な計算を行うことはできません。一部の 10 進数 (0.1 もその 1 つです!) は、2 進数で繰り返しのない表現さえありません。このような精度要件がある場合、数値が正確に 10 進数 15 桁の既知の精度であることを気にする場合は、数値の別の表現を選択する必要があります。

于 2009-10-05T18:13:02.250 に答える
3

いいえ、しかし、これはあなたの問題のいずれかに関連しているかどうか疑問に思います (GCC 固有):

GCC ドキュメント

-float-store 浮動小数点変数をレジスタに格納せず、浮動小数点値がレジスタまたはメモリから取得されるかどうかを変更する可能性のある他のオプションを禁止します。

このオプションは、(68881 の) 浮動レジスターが double の想定よりも高い精度を維持する 68000 などのマシンで、望ましくない過剰な精度を防ぎます。x86 アーキテクチャの場合も同様です。ほとんどのプログラムでは、過剰な精度は有効ですが、少数のプログラムは IEEE 浮動小数点の正確な定義に依存しています。そのようなプログラムには、関連するすべての中間計算を変数に格納するように変更した後、-float-store を使用します。

于 2009-10-05T18:15:50.217 に答える
0

浮動小数点数のフィールドと同じサイズの整数型のユニオンを作成することにより、数値のビットを直接変更できるはずです。次に、必要なビットにアクセスして、必要に応じて設定できます。これは、符号ビットを叩く例です。もちろん、好きなフィールドを選択できます。

#include <stdio.h>

union double_int {
  double             fp;
  unsigned long long integer;
};

int main(int argc, const char *argv[])
{
  double            my_double = 1325.34634;
  union double_int  *my_union = (union double_int *)&my_double;

  /* print original numbers */
  printf("Float   %f\n", my_double);
  printf("Integer %llx\n", my_union->integer);

  /* whack the sign bit to 1 */
  my_union->integer |= 1ULL << 63;

  /* print modified numbers */
  printf("Negative float   %f\n", my_double);
  printf("Negative integer %llx\n", my_union->integer);

  return 0;
}
于 2009-10-05T17:46:22.740 に答える
0

一般的に言えば、数字を表示するとき、人々はこのようなこと (「最初のx桁だけが欲しい」) だけを気にします。stringstreams またはを使用すると比較的簡単sprintfです。

==数値を;と比較することが心配な場合。浮動小数点数では実際にそれを行うことはできません。代わりに、数値が十分に近いかどうかを確認する必要があります (たとえば、epsilon()互いの範囲内)。

数値のビットを直接操作するのは良い考えではありません。

于 2009-10-05T18:35:48.553 に答える