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

Cade Roux
sumber
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>0NR<N

Misalkan , dengan c [ 1 , 2 ) adalah signifikan dan q adalah eksponen bilangan bulat. Biarkan 1 - 2 - s = R dan turunkan batasnyac2q=Nc[1,2)q12s=R

NR=c2q(12s)c2q2qs,

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=1N2qs0.5Nc=12q2qsNc>1NRN.


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));
}
Tyrone
sumber
Maaf, saya agak lambat akhir-akhir ini - Saya mengalami kesulitan mendapatkan bagian dari ketidaksetaraan
c2q2s2qs
Cade Roux
@Cade Tampaknya saya tidak bisa melakukan aljabar hari ini. Maksud saya . 2qs
Tyrone
Terima kasih, saya tidak yakin apakah ada langkah lain yang saya lewatkan.
Cade Roux