presisi 'float' vs 'double'


155

Kode

float x  = 3.141592653589793238;
double z = 3.141592653589793238;
printf("x=%f\n", x);
printf("z=%f\n", z);
printf("x=%20.18f\n", x);
printf("z=%20.18f\n", z);

akan memberi Anda output

x=3.141593
z=3.141593
x=3.141592741012573242
z=3.141592653589793116

dimana pada baris ketiga 741012573242adalah sampah dan pada baris keempat 116adalah sampah. Apakah ganda selalu memiliki 16 angka signifikan sedangkan float selalu memiliki 7 angka signifikan? Mengapa ganda tidak memiliki 14 angka penting?

Jawaban:


146

Nomor titik apung di C menggunakan pengkodean IEEE 754 .

Jenis pengkodean ini menggunakan tanda, signifikansi, dan eksponen.

Karena penyandian ini, banyak angka akan memiliki perubahan kecil untuk memungkinkannya disimpan.

Juga, jumlah digit signifikan dapat berubah sedikit karena itu adalah representasi biner, bukan angka desimal.

Presisi tunggal (float) memberi Anda 23 bit signifikan, 8 bit eksponen, dan 1 bit tanda.

Presisi ganda (ganda) memberi Anda 52 bit signifikan, 11 bit eksponen, dan 1 bit tanda.


4
C99 tidak, sebelumnya terserah kompiler.
Alan Geleynse

21
-1 Pernyataan ini sangat salah: "Karena penyandian ini, Anda tidak pernah dapat menjamin bahwa Anda tidak akan memiliki perubahan nilai Anda."
R .. GitHub BERHENTI MEMBANTU ICE

16
@Lan: C99 tidak memerlukan IEEE floating point; itu hanya merekomendasikannya.
R .. GitHub BERHENTI MEMBANTU ICE

4
@Lan: R .. benar; Lampiran F (yang menentukan ikatan IEEE-754) adalah normatif, tetapi hanya berlaku jika suatu implementasi menentukan __STDC_IEC_559__. Implementasi yang tidak mendefinisikan bahwa makro bebas untuk tidak sesuai dengan IEEE-754.
Stephen Canon

12
@Alan: Di bawah IEEE 754, itu mudah dijamin bahwa tidak ada perubahan dalam nilai-nilai 0.5, 0.046875atau 0.376739501953125dibandingkan representasi desimal mereka. (Ini semua adalah rasional diadic dengan pembilang pas di mantissa dan basis-2 logaritma penyebut pas di eksponen.)
R .. GitHub BERHENTI MEMBANTU ICE

42

Apakah ganda selalu memiliki 16 angka signifikan sedangkan float selalu memiliki 7 angka signifikan?

Tidak. Doubles selalu memiliki 53 bit signifikan dan float selalu memiliki 24 bit signifikan (kecuali untuk denormals, infinities, dan nilai NaN, tetapi itu adalah subjek untuk pertanyaan yang berbeda). Ini adalah format biner, dan Anda hanya dapat berbicara dengan jelas tentang ketepatan representasi mereka dalam hal angka biner (bit).

Ini analog dengan pertanyaan tentang berapa digit yang dapat disimpan dalam bilangan bulat biner: bilangan bulat 32 bit yang tidak ditandatangani dapat menyimpan bilangan bulat hingga 32 bit, yang tidak secara tepat memetakan ke sejumlah angka desimal: semua bilangan bulat hingga 9 digit desimal dapat disimpan, tetapi banyak nomor 10 digit dapat disimpan juga.

Mengapa ganda tidak memiliki 14 angka penting?

Pengkodean ganda menggunakan 64 bit (1 bit untuk tanda, 11 bit untuk eksponen, 52 bit signifikan eksplisit dan satu bit implisit), yang dua kali lipat jumlah bit yang digunakan untuk mewakili float (32 bit).


15

float: 23 bit signifikan, 8 bit eksponen, dan 1 bit tanda.

ganda: 52 bit signifikansi, 11 bit eksponen, dan 1 bit tanda.


11

Biasanya didasarkan pada angka signifikan eksponen dan signifikansi pada basis 2, bukan basis 10. Dari apa yang dapat saya katakan dalam standar C99, bagaimanapun, tidak ada presisi yang ditentukan untuk mengapung dan ganda (selain fakta bahwa 1 dan 1 + 1E-5/ 1 + 1E-7dapat dibedakan [ floatdandouble berulang]). Namun, jumlah angka signifikan diserahkan kepada pelaksana (serta basis mana yang mereka gunakan secara internal, sehingga dengan kata lain, suatu implementasi dapat memutuskan untuk membuatnya berdasarkan pada 18 digit presisi pada basis 3). [1]

Jika Anda perlu mengetahui nilai-nilai ini, konstanta FLT_RADIXdan FLT_MANT_DIG(dan DBL_MANT_DIG/ LDBL_MANT_DIG) didefinisikan dalam float.h.

Alasan itu disebut a doubleadalah karena jumlah byte yang digunakan untuk menyimpannya adalah dua kali lipat jumlah float (tetapi ini termasuk eksponen dan signifikansi). Standar IEEE 754 (digunakan oleh kebanyakan kompiler) mengalokasikan bit relatif lebih banyak untuk signifikansi daripada eksponen (23 hingga 9 untuk floatvs 52 hingga 12 untukdouble ), itulah mengapa presisi lebih dari dua kali lipat.

1: Bagian 5.2.4.2.2 ( http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf )


Salah ketik? C89 membutuhkan epsilon paling banyak 1E-9untuk double, bukan 1E-7.
Rufflewind


4

Ini bukan presisi ganda karena bagaimana IEEE 754 , dan karena biner tidak benar-benar menerjemahkan dengan baik ke desimal. Lihatlah standar jika Anda tertarik.


4

float adalah singkatan dari floating point number. Di C, tipe data float digunakan dalam kasus-kasus di mana ketepatan jumlah total digit adalah 7.Untuk misalnya: - desimal no. 12.3546987 tidak dapat disimpan dalam float karena memiliki total 9 digit. Output akan ditampilkan sebagai 12.354699 yaitu 7 digit pertama akan ditampilkan seperti yang dimasukkan dalam input dan digit ke-8 akan dibulatkan. Tipe float dapat mewakili nilai mulai dari sekitar 1,5 x 10 ^ (- 45) hingga 3,4 x 10 ^ (38). Dalam hal alokasi memori, float adalah tipe data titik mengambang 32-bit presisi tunggal.

Tidak seperti float, double memiliki presisi 15 hingga 16 digit. Kisaran double adalah 5,0 × 10 ^ (- 345) hingga 1,7 × 10 ^ (308). Dalam hal alokasi byte, ganda adalah data floating point 64-bit Tipe.

Masalah muncul dalam penggunaannya. Float atau double tidak mempengaruhi printf tetapi dalam kasus scanf tipe data yang sesuai akan digunakan tergantung pada jumlah total. digit di no mengambang. itu harus dibaca dari input.

Oleh karena itu ganda lebih disukai daripada float untuk akurasi data yang lebih tinggi.

Semoga ini membantu.

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.