Apa integer "no-floating" terbesar yang dapat disimpan dalam tipe ganda IEEE 754 tanpa kehilangan presisi?
Apa integer "no-floating" terbesar yang dapat disimpan dalam tipe ganda IEEE 754 tanpa kehilangan presisi?
Jawaban:
Bilangan bulat terbesar / terbesar yang dapat disimpan dalam dua kali lipat tanpa kehilangan presisi adalah sama dengan nilai kemungkinan terbesar dari suatu ganda. Yaitu, DBL_MAX
atau sekitar 1,8 × 10 308 (jika ganda Anda adalah ganda IEEE 754 64-bit). Itu bilangan bulat. Itu persis diwakili. Apa lagi yang kamu inginkan?
Ayo, tanya saya apa bilangan bulat terbesar, sehingga itu dan semua bilangan bulat yang lebih kecil dapat disimpan dalam ganda IEEE 64-bit tanpa kehilangan presisi. IEEE 64-bit double memiliki 52 bit mantissa, jadi saya pikir ini adalah 53 53 :
Atau cara lain untuk melihatnya: sekali bias telah diambil dari eksponen, dan mengabaikan bit tanda sebagai tidak relevan dengan pertanyaan, nilai yang disimpan oleh ganda adalah kekuatan 2, ditambah bilangan bulat 52-bit dikalikan dengan 2 eksponen - 52 . Jadi dengan eksponen 52 Anda dapat menyimpan semua nilai dari 2 52 hingga 2 53 - 1. Kemudian dengan eksponen 53, angka berikutnya yang dapat Anda simpan setelah 2 53 adalah 2 53 + 1 × 2 53 - 52 . Jadi kehilangan presisi pertama kali terjadi dengan 2 53 + 1.
9007199254740992 (yaitu 9.007.199.254.740.992) tanpa jaminan :)
Program
#include <math.h>
#include <stdio.h>
int main(void) {
double dbl = 0; /* I started with 9007199254000000, a little less than 2^53 */
while (dbl + 1 != dbl) dbl++;
printf("%.0f\n", dbl - 1);
printf("%.0f\n", dbl);
printf("%.0f\n", dbl + 1);
return 0;
}
Hasil
9007199254740991 9007199254740992 9007199254740992
double dbl = 1; while (dbl + 1 != dbl) dbl *= 2; while (dbl == --dbl);
yang menghasilkan hasil yang sama
while (dbl == --dbl)
akan berulang selamanya atau tidak sama sekali. :) (dalam hal ini, tidak sama sekali, karena ini adalah 2 ^ N). Anda harus mendekatinya dari bawah. Ini memang juga akan menghasilkan satu kurang dari hasil yang diharapkan (karena yang memeriksa di while loop mengurangi dbl). Dan itu tergantung pada urutan eksekusi, jika pengurangan dilakukan sebelum atau setelah mengevaluasi sisi kiri (yang tidak ditentukan sejauh yang saya tahu). Jika yang pertama, itu akan selalu benar dan berulang selamanya.
while (dbl + 1 != dbl) dbl++;
dalam yang dbl + 1 != dbl
dapat mengevaluasi menggunakan long double
matematika - pertimbangkan FLT_EVAL_METHOD == 2
. Ini bisa berakhir dalam loop tak terbatas.
Wikipedia mengatakan ini dalam konteks yang sama dengan tautan ke IEEE 754 :
Pada sistem komputer tipikal, angka biner floating-point 'presisi ganda' (64-bit) memiliki koefisien 53 bit (salah satunya tersirat), eksponen 11 bit, dan satu bit tanda.
2 ^ 53 lebih dari 9 * 10 ^ 15.
Bilangan bulat terbesar yang dapat direpresentasikan dalam IEEE 754 ganda (64-bit) adalah sama dengan nilai terbesar yang dapat diwakili oleh jenis tersebut, karena nilai itu sendiri merupakan bilangan bulat.
Ini direpresentasikan sebagai 0x7FEFFFFFFFFFFFFF
, yang terdiri dari:
0x7FE
(2046 yang mewakili 1023 setelah bias dikurangi) daripada 0x7FF
(2047 yang menunjukkan a NaN
atau tak terbatas).0xFFFFFFFFFFFFF
yaitu 52 bit semua 1.Dalam biner, nilainya adalah implisit 1 diikuti oleh 52 yang lain dari mantissa, kemudian 971 nol (1023 - 52 = 971) dari eksponen.
Nilai desimal yang tepat adalah:
179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368
Ini sekitar 1,8 x 10 308 .
Anda perlu melihat ukuran mantissa. Nomor floating point IEEE 754 64 bit (yang memiliki 52 bit, ditambah 1 tersirat) dapat mewakili integer dengan nilai absolut kurang dari atau sama dengan 2 ^ 53.
1.7976931348623157 × 10 ^ 308
http://en.wikipedia.org/wiki/Double_precision_floating-point_format
DECIMAL_DIG
dari <float.h>
harus memberikan setidaknya perkiraan yang masuk akal itu. Karena itu berkaitan dengan angka desimal, dan itu benar-benar disimpan dalam biner, Anda mungkin dapat menyimpan sesuatu yang sedikit lebih besar tanpa kehilangan presisi, tetapi seberapa banyak yang sulit dikatakan. Saya kira Anda harus bisa mengetahuinya FLT_RADIX
dan DBL_MANT_DIG
, tapi saya tidak yakin saya sepenuhnya percaya hasilnya.
double
berhubungan langsung dengan jenis IEEE tertentu, tetapi itu tidak diperlukan, dan ketika jawaban ini ditulis, pertanyaannya tidak menyebutkan jenis IEEE tertentu juga.