浮動小数点の丸め


13

IEEE-754の浮動小数点数<1(つまり、数値> = 0.0および<1.0を生成する乱数ジェネレーターで生成)に整数(浮動小数点形式)を掛けて、それ以上の数値を取得できますか丸めのためにその整数?

すなわち

double r = random() ; // generates a floating point number in [0, 1)
double n = some_int ;
if (n * r >= n) {
    print 'Rounding Happened' ;
}

これは、Rが存在し、RがIEEE-754で表現できる1未満の最大数である場合、N * R> = N(*および> =が適切なIEEE- 754人のオペレーター)

これは、このドキュメントとpostgresql ランダム関数に基づいたこの質問から来ています


Nの範囲について何か言えますか。つまり、IEEE-754倍精度で正確に表現できるほど小さいのでしょうか。
ペドロ

@Pedroこの特定の場合、はい、それは小さな整数、つまり10になります。Nが非常に多くの有効桁を持つ非常に大きな整数である場合、正確に表現できないかもしれないと言っていると思いますか?
ケードルー

正確に、場合、f l R × f l N R Nより大きくなる可能性があります。fl(N)>Nfl(R×fl(N))RN
ペドロ

回答:


8

最も近い値に丸め、であると仮定すると、N R < N常になります。(大きすぎる整数を変換しないように注意してください。)N>0NR<N

c2q=Nc[1,2)q12s=R

NR=c2q(12s)c2q2qs,

c=1N2qs0.5Nc=12q2qsNc>1NRN


上方への丸めは問題を引き起こす可能性がありますが、疑いを持たないユーザーの存在下で選択されるべきではありません。これ"0\n1\n"が私のマシンで印刷するC99です。

#include <fenv.h>
#include <math.h>
#include <stdio.h>

int main(void) {
    double n = 10;
    double r = nextafter(1, 0);
    printf("%d\n", n == (n * r));
    fesetround(FE_UPWARD);
    printf("%d\n", n == (n * r));
}

c2q2s2qs

2qs

おかげで、私が行方不明になっていた別のステップがあるかどうかはわかりませんでした。
ケードルー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.