Adakah terdapat masalah dengan aritmetik titik terapung?
P粉330232096
P粉330232096 2023-08-21 15:24:30
0
2
510
<p>Pertimbangkan kod berikut: </p> <pre class="brush:js;toolbar:false;">0.1 + 0.2 == 0.3 -> </pra> <pre class="brush:js;toolbar:false;">0.1 + 0.2 -> </pra> <p>Mengapakah ketidaktepatan ini berlaku? </p>
P粉330232096
P粉330232096

membalas semua(2)
P粉041856955

Perspektif Pereka Perkakasan

Saya fikir saya akan menambah beberapa perspektif daripada perspektif pereka perkakasan, kerana saya mereka bentuk dan membina perkakasan titik terapung. Mengetahui asal usul ralat boleh membantu memahami perkara yang berlaku dalam perisian, dan akhirnya, saya harap ini membantu menjelaskan sebab ralat titik terapung berlaku dan nampaknya terkumpul dari semasa ke semasa.

1. Gambaran keseluruhan

Dari perspektif kejuruteraan, kebanyakan operasi titik terapung akan mempunyai sedikit ralat kerana perkakasan yang melakukan pengiraan titik terapung hanya perlu mempunyai ralat satu unit di bawah separuh bit terakhir. Oleh itu, kebanyakan perkakasan akan berhenti pada ketepatan yang hanya memerlukan menghasilkan kurang daripada separuh ralat bit terakhir dalam satu operasi, yang amat rumit dalam pembahagian titik terapung. Apa yang membentuk satu operasi bergantung kepada bilangan operan yang diterima oleh unit. Untuk kebanyakan unit, ia adalah dua, tetapi sesetengah unit menerima 3 atau lebih operan. Oleh itu, tiada jaminan bahawa operasi berulang akan menghasilkan ralat yang ideal, kerana ralat ini akan terkumpul dari semasa ke semasa.

2

Kebanyakan pemproses mengikut piawai

IEEE-754, tetapi sesetengahnya menggunakan piawaian yang tidak normal atau berbeza. Sebagai contoh, terdapat mod penyahnormalan dalam IEEE-754 yang membenarkan nombor titik terapung yang sangat kecil diwakili dengan mengorbankan ketepatan. Walau bagaimanapun, yang berikut menerangkan mod ternormal IEEE-754, yang merupakan mod pengendalian biasa.

Dalam standard IEEE-754, pereka perkakasan boleh memilih sebarang nilai ralat/epsilon asalkan kurang daripada separuh unit bit terakhir, dan hasilnya hanya perlu kurang daripada separuh unit bit terakhir dalam satu operasi. Ini menerangkan sebab ralat terkumpul sepanjang operasi berulang. Untuk ketepatan berganda IEEE-754, ini adalah bit 54 kerana terdapat 53 bit yang digunakan untuk mewakili bahagian berangka (bahagian ternormal) nombor titik terapung, juga dipanggil mantissa (cth. 5.3 dalam 5.3e5). Beberapa bahagian seterusnya akan melihat dengan lebih terperinci tentang punca ralat perkakasan dalam pelbagai operasi titik terapung.

3 Punca kesilapan pembahagian dan pembundaran

Punca utama ralat dalam pembahagian titik terapung ialah algoritma bahagi yang digunakan untuk mengira hasil bahagi. Kebanyakan sistem komputer menggunakan pendaraban songsang untuk mengira pembahagian, terutamanya dalam bit

(ditambah beberapa bit pilihan). Z=X/YZ = X * (1/Y)中。除法是迭代计算的,即每个周期计算一些商的位数,直到达到所需的精度,对于IEEE-754来说,这是任何误差小于最后一位的一半以下的内容。Y的倒数表(1/Y)称为慢除法中的商选择表(QST),商选择表的位数通常是基数的宽度,或者每次迭代计算的商的位数加上几个保护位。对于IEEE-754标准的双精度(64位),它将是除法器的基数大小加上几个保护位k,其中k>=2。因此,例如,一个每次计算2位商(基数为4)的典型商选择表将是2+2= 4

3.1 Ralat pembundaran bahagian: penghampiran timbal balik

Timbal balik dalam jadual pemilihan hasil bagi bergantung pada kaedah bahagi: pembahagian perlahan (seperti pembahagian SRT) atau pembahagian pantas (seperti pembahagian Goldschmidt); setiap entri diubah suai mengikut algoritma pembahagian untuk meminimumkan ralat. Walau apa pun, semua timbal balik adalah hampiran salingan sebenar dan memperkenalkan sejumlah ralat. Kedua-dua kaedah pembahagian perlahan dan pembahagian pantas mengira hasil bahagi secara berulang, iaitu, setiap langkah mengira bilangan digit hasil bahagi tertentu, kemudian menolak hasil daripada dividen, dan pembahagi mengulangi langkah ini sehingga ralat kurang daripada separuh daripada yang terakhir. digit. Kaedah pembahagian perlahan mengira bilangan digit hasil bahagi yang tetap dalam setiap langkah dan secara amnya lebih murah, manakala kaedah pembahagian pantas mengira nombor pembolehubah digit hasil dalam setiap langkah dan secara amnya lebih mahal. Bahagian paling penting tentang kaedah bahagi ialah kebanyakannya bergantung pada pendaraban berulang dengan menghampiri timbal balik , jadi mereka terdedah kepada ralat.

4. Ralat pembulatan dalam operasi lain: pemotongan

Satu lagi punca ralat pembundaran dalam semua operasi ialah mod pemangkasan berbeza yang dibenarkan oleh IEEE-754. Terdapat potong, bulatkan ke arah sifar, bundarkan kepada terdekat (lalai) , bulatkan ke bawah dan bundarkan ke atas. Semua kaedah memperkenalkan ralat kurang daripada setengah unit bit terakhir untuk satu operasi. Dari masa ke masa dan operasi berulang, pemotongan juga terkumpul ke dalam ralat yang terhasil. Ralat pemangkasan ini amat menyusahkan dalam operasi eksponen yang melibatkan beberapa bentuk pendaraban berulang.

5. Ulangi operasi

Memandangkan perkakasan yang melakukan pengiraan titik terapung hanya perlu menghasilkan keputusan dengan kurang daripada separuh ralat bit terakhir unit dalam satu operasi, jika tidak diperhatikan, ralat akan meningkat apabila operasi diulang. Inilah sebabnya mengapa dalam pengiraan yang memerlukan ralat terhad, ahli matematik menggunakan kaedah seperti menggunakan angka genap bulat terdekat IEEE-754, kerana ralat lebih berkemungkinan untuk membatalkan satu sama lain dari semasa ke semasa, dan aritmetik selang Menggabungkan varian IEEE 754 mod pembundaran untuk meramal ralat pembundaran dan membetulkannya. Membundarkan kepada digit genap terdekat (pada bit terakhir) ialah mod pembundaran lalai untuk IEEE-754 disebabkan oleh ralat relatif yang lebih rendah berbanding dengan mod pembundaran lain.

Sila ambil perhatian bahawa mod pembundaran lalai, membundarkan kepada digit genap terdekat, menjamin operasi dengan ralat kurang daripada setengah unit digit terakhir. Menggunakan hanya pemangkasan, bulatkan dan bulatkan ke bawah boleh mengakibatkan ralat lebih besar daripada setengah unit digit terakhir tetapi kurang daripada satu unit digit terakhir, jadi melainkan anda mengira pada selang waktu

P粉041881924

BinaryFloating pointoperasi adalah seperti ini. Dalam kebanyakan bahasa pengaturcaraan, ia adalah berdasarkan IEEE 754 standard. Intinya ialah nombor diwakili dalam format ini sebagai integer dikali kuasa dua nombor rasional yang penyebutnya bukan kuasa dua (seperti 0.1,即1/10) tidak boleh diwakili dengan tepat.

Untuk standard binary64格式中的0.1, representasinya boleh ditulis betul-betul seperti

Sebaliknya, nombor rasional 0.1,即1/10, boleh ditulis tepat seperti

  • 0.1 (perpuluhan), atau
  • 0x1.99999999999999...p-4(类似于C99十六进制浮点表示法,其中... mewakili urutan 9 yang tidak berkesudahan).

Pemalar 0.2 dan 0.3 dalam program anda juga akan menjadi anggaran nilai sebenar mereka. Tepat 0.2 double terdekat adalah lebih besar daripada nombor rasional 0.2, tetapi double terdekat adalah kurang daripada rasional nombor 0.3. Jumlah 0.20.3也将是它们真实值的近似值。恰好0.2最接近的double大于有理数0.2,但最接近的double小于有理数0.30.10.2的和最终大于有理数0.3 dan 0.2 akhirnya menjadi lebih besar daripada nombor rasional 0.3, jadi ia tidak konsisten dengan pemalar dalam kod.

Satu rawatan yang agak menyeluruh bagi aritmetik titik terapung ialah "Apa yang Ahli Sains Komputer Patut Tahu Mengenai Aritmetik Titik Terapung". Untuk penjelasan yang lebih mudah difahami, lihat floating-point-gui.de.

Masalah yang sama wujud dengan nombor perpuluhan biasa (asas 10), itulah sebabnya nombor seperti 1/3 berakhir sebagai 0.333333333...

Anda baru sahaja menemui nombor (3/10) yang mudah diwakili dalam sistem perpuluhan, tetapi tidak boleh diwakili dalam sistem binari. Situasi juga terbalik (dalam satu cara): 1/16 ialah nombor hodoh dalam perpuluhan (0.0625), tetapi kelihatan kemas dalam binari seperti 1/10000 dalam perpuluhan (0.0001)** - Jika kita biasa menggunakan nombor binari sistem dalam kehidupan harian kita, anda akan melihat nombor itu dan secara naluri memahami bahawa anda boleh mendapatkannya dengan sentiasa melipat dua.

Sudah tentu, ini bukan cara nombor titik terapung disimpan dalam ingatan (ia menggunakan bentuk tatatanda saintifik). Walau bagaimanapun, ia menggambarkan bahawa ralat ketepatan titik terapung binari cenderung timbul kerana nombor "dunia nyata" yang biasanya kita minati cenderung kepada kuasa sepuluh - tetapi hanya kerana kita menggunakan sistem nombor perpuluhan setiap hari. Itulah sebabnya kami menyebut 71% dan bukannya "5 daripada setiap 7" (71% ialah anggaran, kerana tiada nombor perpuluhan boleh mewakili 5/7 dengan tepat).

Jadi tidak, nombor titik terapung binari tidak rosak, ia hanya tidak sempurna seperti sistem nombor asas N yang lain :)

Dalam amalan, isu ketepatan ini bermakna anda perlu menggunakan fungsi pembundaran untuk membundarkan nombor titik terapung kepada bilangan tempat perpuluhan yang anda minati sebelum memaparkannya.

Anda juga perlu menggantikan ujian kesamarataan dengan perbandingan yang membolehkan toleransi tertentu, yang bermaksud:

Jangan gunaif (x == y) { ... }

Gunakan if (abs(x - y) < myToleranceValue) { ... } sebaliknya.

Di mana abs是绝对值函数。需要根据您的特定应用选择myToleranceValue - Ini mempunyai banyak kaitan dengan berapa banyak "ruang goyang" yang anda sediakan untuk membenarkan dan bilangan maksimum yang anda bandingkan (disebabkan oleh isu kehilangan ketepatan). Sila ambil perhatian pemalar gaya "epsilon" dalam bahasa pilihan anda. Pemalar ini boleh digunakan sebagai nilai toleransi, tetapi keberkesanannya bergantung pada saiz nombor yang anda gunakan (memandangkan pengiraan nombor besar mungkin melebihi ambang epsilon).

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!