Pembulatan titik mengambang


13

Dapatkah nomor floating point IEEE-754 <1 (yaitu dihasilkan dengan generator angka acak yang menghasilkan angka> = 0,0 dan <1.0) pernah dikalikan dengan beberapa bilangan bulat (dalam bentuk floating point) untuk mendapatkan angka yang sama atau lebih besar dari integer itu karena pembulatan?

yaitu

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

Ini mungkin sama dengan mengatakan bahwa apakah ada N dan R sedemikian rupa sehingga jika R adalah angka terbesar kurang dari 1 yang dapat direpresentasikan dalam IEEE-754 maka N * R> = N (di mana * dan> = sesuai IEEE- 754 operator)

Ini berasal dari pertanyaan ini berdasarkan pada dokumentasi ini dan fungsi acak postgresql


Bisakah Anda mengatakan apa-apa tentang kisaran N, yaitu apakah cukup kecil untuk diwakili tepat dalam presisi ganda IEEE-754?
— Pedro

@Pedro Dalam kasus khusus ini, ya, itu akan menjadi bilangan bulat kecil - yaitu 10. Saya berasumsi Anda mengatakan bahwa jika N adalah bilangan bulat yang sangat besar dengan jumlah digit signifikan yang sangat besar mungkin tidak dapat diwakili dengan tepat?
— Cade Roux

Tepat, jika , maka f l ( R × f l ( N ) ) mungkin lebih besar dari R N . fl(N)>Nfl(R×fl(N))RN
— Pedro

Jawaban:


8

Dengan asumsi bulat ke terdekat dan bahwa , maka N ∗ R < N selalu. (Hati-hati untuk tidak mengonversi bilangan bulat yang terlalu besar.)N>0N∗R<N

Misalkan , dengan c ∈ [ 1 , 2 ) adalah signifikan dan q adalah eksponen bilangan bulat. Biarkan 1 - 2 - s = R dan turunkan batasnyac2−q=Nc∈[1,2)q1−2−s=R

NR=c2−q(1−2−s)≤c2−q−2−q−s,

dengan persamaan jika dan hanya jika . Sisi kanan kurang dari N dan, karena 2 - q - s adalah tepat 0,5 unit di tempat terakhir N , baik c = 1 dan 2 - q - 2 - q - s persis dapat direpresentasikan (karena N adalah normal dan bukan yang terkecil normal), atau c > 1 , dan pembulatan terdekat turun. Dalam kedua kasus, N ∗ R kurang dari Nc=1N2−q−s0.5Nc=12−q−2−q−sNc>1N∗RN.


Pembulatan ke atas dapat menyebabkan masalah, bukan karena itu harus dipilih di hadapan pengguna yang tidak curiga. Inilah beberapa C99 yang dicetak "0\n1\n"pada mesin saya.

#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));
}

Maaf, saya agak lambat akhir-akhir ini - Saya mengalami kesulitan mendapatkan bagian dari ketidaksetaraan
−c2−q2−s≤−2−qs
— Cade Roux

@Cade Tampaknya saya tidak bisa melakukan aljabar hari ini. Maksud saya . 2−q−s
— Tyrone

Terima kasih, saya tidak yakin apakah ada langkah lain yang saya lewatkan.
— Cade Roux
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.