Saya percaya saya harus menambah perspektif pereka perkakasan, kerana saya mereka bentuk dan membina perkakasan titik terapung. Mengetahui punca 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 mengalami sedikit ralat kerana perkakasan yang melakukan pengiraan titik terapung hanya perlu mempunyai ralat kurang daripada setengah unit dalam bit terakhir. Oleh itu, banyak perkakasan akan berhenti pada ketepatan yang hanya memerlukan ralat kurang daripada satu unit pada bit terakhir operasi tunggal , yang amat bermasalah dalam pembahagian titik terapung. Apa yang membentuk satu operasi bergantung pada berapa banyak operan yang diperlukan untuk unit itu. Bagi kebanyakan, ia adalah dua, tetapi sesetengah unit memerlukan 3 atau lebih operan. Oleh itu, tiada jaminan bahawa operasi berulang akan menghasilkan ralat yang diingini, kerana ralat terkumpul dari semasa ke semasa.
Dalam piawaian IEEE-754, pereka perkakasan dibenarkan menggunakan sebarang nilai ralat/epsilon asalkan kurang daripada separuh daripada unit digit terakhir, dan hasilnya hanya perlu kurang daripada separuh daripada satu unit untuk digunakan sekaligus Kedudukan terakhir operasi. Ini menerangkan sebab ralat terkumpul apabila operasi diulang. Untuk ketepatan berganda IEEE-754, ini adalah bit 54 kerana bit 53 digunakan untuk mewakili bahagian berangka (dinormalkan) nombor titik terapung, juga dikenali sebagai mantissa (cth. 5.3 dalam 5.3e5). Bahagian berikut menerangkan dengan lebih terperinci tentang punca ralat perkakasan dalam pelbagai operasi titik terapung.
3. Punca kesilapan pembahagian dan pembundaran
Punca utama ralat pembahagian titik terapung ialah algoritma pembahagian yang digunakan untuk mengira hasil bahagi. Kebanyakan sistem komputer menggunakan pendaraban songsang untuk mengira pembahagian, terutamanya
bit (ditambah beberapa bit pilihan). Z=X/Y、Z = 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 quotient bergantung pada divisyen: bahagian perlahan seperti bahagian SRT, atau bahagian pantas seperti bahagian Goldschmidt setiap entri diubah suai mengikut algoritma bahagian untuk cuba menghasilkan ralat yang paling rendah. Walau apa pun, semua salingan adalah anggaran salingan sebenar dan akan memperkenalkan beberapa unsur ralat. Kedua-dua pembahagian perlahan dan pembahagian pantas mengira hasil bahagi secara berulang, iaitu setiap langkah mengira bilangan digit dalam hasil bahagi dan kemudian menolak hasil daripada dividen Pembahagi mengulangi langkah ini sehingga ralat kurang daripada setengah unit di tempat terakhir . Kaedah pembahagian perlahan mengira hasil bagi bilangan digit yang tetap dalam setiap langkah dan secara amnya lebih murah untuk dibina, manakala kaedah pembahagian pantas mengira bilangan digit yang berubah-ubah dalam setiap langkah dan secara amnya lebih mahal untuk dibina. Bahagian yang paling penting tentang pembahagian ialah kebanyakannya bergantung pada pendaraban berulang bagi hampiran timbal balik, jadi mudah untuk membuat kesilapan.
4. Ralat pembundaran dalam operasi lain: pemangkasan
Sebab lain untuk ralat pembundaran dalam semua operasi ialah mod pemangkasan berbeza bagi jawapan akhir yang dibenarkan oleh IEEE-754. Terdapat potong, bulat ke arah sifar, bulat ke terdekat (lalai), bulat ke bawah, bundarkan ke atas. Untuk satu operasi, semua kaedah memperkenalkan elemen ralat kurang daripada satu unit pada penghujungnya. Pemangkasan juga secara kumulatif meningkatkan ralat akhir dari semasa ke semasa dan dengan operasi berulang. Ralat pemangkasan ini amat bermasalah apabila pengeksponenan melibatkan beberapa bentuk pendaraban berulang.
5. Ulang operasi
Oleh kerana perkakasan yang melakukan pengiraan titik terapung hanya perlu menghasilkan keputusan dengan ralat kurang daripada separuh dalam bit terakhir dalam satu operasi, jika anda tidak berhati-hati, ralat akan meningkat dengan operasi berulang. Inilah sebabnya mengapa dalam pengiraan yang memerlukan ralat terhad, ahli matematik menggunakan kaedah seperti membundarkan kepada Aritmetik Selang digabungkan dengan varian Mod Pembundaran IEEE 754 untuk meramalkan ralat pembundaran dan membetulkannya. Membundarkan kepada digit genap terdekat (digit terakhir) ialah mod pembundaran lalai untuk IEEE-754 disebabkan oleh ralat relatif yang lebih rendah berbanding dengan mod pembundaran lain.
Ringkasnya, punca ralat dalam operasi floating point adalah gabungan pemangkasan perkakasan dan pemangkasan timbal balik semasa pembahagian. Oleh kerana piawaian IEEE-754 hanya memerlukan ralat dalam bit terakhir operasi tunggal kurang daripada separuh, ralat titik terapung daripada operasi berulang akan terkumpul melainkan diperbetulkan.
Binary Floating pointMath macam ni. Dalam kebanyakan bahasa pengaturcaraan, ia berdasarkan standard IEEE 754. Inti dari perkara ini ialah nombor diwakili dalam format ini sebagai integer yang didarab dengan kuasa 2 yang penyebutnya bukan kuasa 2 (seperti 0.1,即1/10) tidak boleh diwakili dengan tepat.
Untuk standard binary64 格式的 0.1, representasinya boleh ditulis betul-betul seperti
0.10000000000000000055511151231257827021181583404541015625 (perpuluhan), atau
Sebaliknya, nombor rasional0.1,即1/10, boleh ditulis tepat seperti
0.1 (perpuluhan), atau
0x1.99999999999999...p-4 类似于 C99 十六进制浮点表示法,其中 ... bermaksud urutan 9s yang tidak berkesudahan.
Pemalar 0.2 dan 0.3 dalam program juga akan menjadi anggaran nilai sebenar mereka. Seperti yang berlaku, double yang paling hampir dengan 0.2 adalah lebih besar daripada nombor rasional 0.2, tetapi yang paling hampir dengan double kod>0.3 Kurang daripada nombor rasional 0.3. Jumlah 0.2和0.3也将是其真实值的近似值。碰巧,最接近 0.2 的 double 大于有理数 0.2,但最接近 double code>0.3 小于有理数 0.3。 0.1 和 0.2 的总和最终大于有理数 0.3 dan 0.2 akhirnya menjadi lebih besar daripada nombor rasional 0.3 dan oleh itu tidak konsisten dengan pemalar dalam kod.
Nombor perpuluhan lama biasa (asas 10) mempunyai masalah yang sama, sebab itu nombor seperti 1/3 akhirnya menjadi 0.333333333...
Anda baru sahaja terjumpa nombor (3/10) yang mudah diwakili dalam perpuluhan, tetapi tidak dalam sistem binari. Ia juga berjalan kedua-dua arah (pada tahap tertentu): 1/16 ialah nombor yang jelek dalam perpuluhan (0.0625), tetapi dalam perduaan ia kelihatan seperti perpuluhan ke-10,000 (0.0001)** - jika kita sudah tiba masanya. tabiat menggunakan sistem nombor asas 2 dalam kehidupan seharian kita, malah anda akan melihat nombor itu dan secara naluriah memahami bahawa anda boleh mencapai nombor itu dengan mengurangkan separuh sesuatu, dan mengurangkan separuh lagi, dan lagi dan lagi.
Sudah tentu, ini bukan cara nombor terapung disimpan dalam ingatan (ia menggunakan tatatanda saintifik). Walau bagaimanapun, ia menggambarkan bahawa ralat ketepatan titik terapung binari cenderung timbul kerana nombor "dunia nyata" yang biasanya kita minati biasanya adalah kuasa sepuluh - tetapi itu hanya kerana kita menggunakan sistem penomboran perpuluhan hari ini - hari ini. Itulah sebabnya kami menyebut 71% dan bukannya "5 daripada setiap 7" (71% ialah anggaran kerana 5/7 tidak boleh diwakili dengan tepat oleh sebarang nombor perpuluhan).
Jadi tidak: nombor titik terapung binari tidak rosak, ia kebetulan tidak sempurna seperti sistem nombor berasaskan 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 kesaksamaan dengan perbandingan yang membolehkan tahap toleransi tertentu, yang bermaksud:
Jangan jangan buat if (x == y) { ... }
Sebaliknya laksanakan if (abs(x - y) .
Yang manakah abs 是绝对值。 myToleranceValue perlu dipilih berdasarkan aplikasi khusus anda - ia mempunyai banyak kaitan dengan "bilik goyang" yang anda sediakan untuk membenarkan, dan kemungkinan jumlah terbesar yang anda bandingkan (disebabkan oleh isu kehilangan ketepatan) . Perhatikan pemalar gaya "epsilon" dalam bahasa pilihan anda. Ini boleh digunakan sebagai nilai toleransi, tetapi keberkesanannya bergantung pada saiz (saiz) nombor yang anda gunakan, kerana pengiraan pada nombor besar mungkin melebihi ambang epsilon.
Perspektif Pereka Perkakasan
Saya percaya saya harus menambah perspektif pereka perkakasan, kerana saya mereka bentuk dan membina perkakasan titik terapung. Mengetahui punca 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 mengalami sedikit ralat kerana perkakasan yang melakukan pengiraan titik terapung hanya perlu mempunyai ralat kurang daripada setengah unit dalam bit terakhir. Oleh itu, banyak perkakasan akan berhenti pada ketepatan yang hanya memerlukan ralat kurang daripada satu unit pada bit terakhir operasi tunggal , yang amat bermasalah dalam pembahagian titik terapung. Apa yang membentuk satu operasi bergantung pada berapa banyak operan yang diperlukan untuk unit itu. Bagi kebanyakan, ia adalah dua, tetapi sesetengah unit memerlukan 3 atau lebih operan. Oleh itu, tiada jaminan bahawa operasi berulang akan menghasilkan ralat yang diingini, kerana ralat terkumpul dari semasa ke semasa.
2. StandardIEEE-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, mod piawai IEEE-754 diterangkan di bawah, yang merupakan mod operasi biasa.
Dalam piawaian IEEE-754, pereka perkakasan dibenarkan menggunakan sebarang nilai ralat/epsilon asalkan kurang daripada separuh daripada unit digit terakhir, dan hasilnya hanya perlu kurang daripada separuh daripada satu unit untuk digunakan sekaligus Kedudukan terakhir operasi. Ini menerangkan sebab ralat terkumpul apabila operasi diulang. Untuk ketepatan berganda IEEE-754, ini adalah bit 54 kerana bit 53 digunakan untuk mewakili bahagian berangka (dinormalkan) nombor titik terapung, juga dikenali sebagai mantissa (cth. 5.3 dalam 5.3e5). Bahagian berikut menerangkan dengan lebih terperinci tentang punca ralat perkakasan dalam pelbagai operasi titik terapung.bit (ditambah beberapa bit pilihan).
Z=X/Y
、Z = 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 quotient bergantung pada divisyen: bahagian perlahan seperti bahagian SRT, atau bahagian pantas seperti bahagian Goldschmidt setiap entri diubah suai mengikut algoritma bahagian untuk cuba menghasilkan ralat yang paling rendah. Walau apa pun, semua salingan adalah anggaran salingan sebenar dan akan memperkenalkan beberapa unsur ralat. Kedua-dua pembahagian perlahan dan pembahagian pantas mengira hasil bahagi secara berulang, iaitu setiap langkah mengira bilangan digit dalam hasil bahagi dan kemudian menolak hasil daripada dividen Pembahagi mengulangi langkah ini sehingga ralat kurang daripada setengah unit di tempat terakhir . Kaedah pembahagian perlahan mengira hasil bagi bilangan digit yang tetap dalam setiap langkah dan secara amnya lebih murah untuk dibina, manakala kaedah pembahagian pantas mengira bilangan digit yang berubah-ubah dalam setiap langkah dan secara amnya lebih mahal untuk dibina. Bahagian yang paling penting tentang pembahagian ialah kebanyakannya bergantung pada pendaraban berulang bagi hampiran timbal balik, jadi mudah untuk membuat kesilapan.
4. Ralat pembundaran dalam operasi lain: pemangkasan
Sebab lain untuk ralat pembundaran dalam semua operasi ialah mod pemangkasan berbeza bagi jawapan akhir yang dibenarkan oleh IEEE-754. Terdapat potong, bulat ke arah sifar, bulat ke terdekat (lalai), bulat ke bawah, bundarkan ke atas. Untuk satu operasi, semua kaedah memperkenalkan elemen ralat kurang daripada satu unit pada penghujungnya. Pemangkasan juga secara kumulatif meningkatkan ralat akhir dari semasa ke semasa dan dengan operasi berulang. Ralat pemangkasan ini amat bermasalah apabila pengeksponenan melibatkan beberapa bentuk pendaraban berulang.
5. Ulang operasi
Oleh kerana perkakasan yang melakukan pengiraan titik terapung hanya perlu menghasilkan keputusan dengan ralat kurang daripada separuh dalam bit terakhir dalam satu operasi, jika anda tidak berhati-hati, ralat akan meningkat dengan operasi berulang. Inilah sebabnya mengapa dalam pengiraan yang memerlukan ralat terhad, ahli matematik menggunakan kaedah seperti membundarkan kepada Aritmetik Selang digabungkan dengan varian Mod Pembundaran IEEE 754 untuk meramalkan ralat pembundaran dan membetulkannya. Membundarkan kepada digit genap terdekat (digit 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 nombor genap a> terdekat bagi digit terakhir, memastikan ralat digit terakhir dalam satu operasi adalah kurang daripada separuh. Pemotongan, pembundaran ke atas dan pembundaran ke bawah sahaja boleh mengakibatkan ralat lebih besar daripada separuh daripada digit terakhir tetapi kurang daripada satu unit digit terakhir, jadi mod ini tidak disyorkan kecuali untuk aritmetik selang.
6. Ringkasan
Ringkasnya, punca ralat dalam operasi floating point adalah gabungan pemangkasan perkakasan dan pemangkasan timbal balik semasa pembahagian. Oleh kerana piawaian IEEE-754 hanya memerlukan ralat dalam bit terakhir operasi tunggal kurang daripada separuh, ralat titik terapung daripada operasi berulang akan terkumpul melainkan diperbetulkan.
Binary Floating pointMath macam ni. Dalam kebanyakan bahasa pengaturcaraan, ia berdasarkan standard IEEE 754. Inti dari perkara ini ialah nombor diwakili dalam format ini sebagai integer yang didarab dengan kuasa 2 yang penyebutnya bukan kuasa 2 (seperti
0.1
,即1/10
) tidak boleh diwakili dengan tepat.Untuk standard
binary64
格式的0.1
, representasinya boleh ditulis betul-betul seperti0.10000000000000000055511151231257827021181583404541015625
(perpuluhan), atau0x1.999999999999ap-4
Perwakilan titik terapung heksadesimal C99.Sebaliknya, nombor rasional
0.1
,即1/10
, boleh ditulis tepat seperti0.1
(perpuluhan), atau0x1.99999999999999...p-4
类似于 C99 十六进制浮点表示法,其中...
bermaksud urutan 9s yang tidak berkesudahan.Pemalar
0.2
dan0.3
dalam program juga akan menjadi anggaran nilai sebenar mereka. Seperti yang berlaku,double
yang paling hampir dengan0.2
adalah lebih besar daripada nombor rasional0.2
, tetapi yang paling hampir dengandouble
kod>0.3 Kurang daripada nombor rasional0.3
. Jumlah0.2
和0.3
也将是其真实值的近似值。碰巧,最接近0.2
的double
大于有理数0.2
,但最接近double
code>0.3 小于有理数0.3
。0.1
和0.2
的总和最终大于有理数0.3
dan0.2
akhirnya menjadi lebih besar daripada nombor rasional0.3
dan oleh itu tidak konsisten dengan pemalar dalam kod.Rawatan yang agak menyeluruh bagi masalah aritmetik titik terapung ialah Setiap saintis komputer harus tahu tentang aritmetik titik terapung. Untuk penjelasan yang lebih mudah difahami, lihat floating-point-gui.de.
Nombor perpuluhan lama biasa (asas 10) mempunyai masalah yang sama, sebab itu nombor seperti 1/3 akhirnya menjadi 0.333333333...
Anda baru sahaja terjumpa nombor (3/10) yang mudah diwakili dalam perpuluhan, tetapi tidak dalam sistem binari. Ia juga berjalan kedua-dua arah (pada tahap tertentu): 1/16 ialah nombor yang jelek dalam perpuluhan (0.0625), tetapi dalam perduaan ia kelihatan seperti perpuluhan ke-10,000 (0.0001)** - jika kita sudah tiba masanya. tabiat menggunakan sistem nombor asas 2 dalam kehidupan seharian kita, malah anda akan melihat nombor itu dan secara naluriah memahami bahawa anda boleh mencapai nombor itu dengan mengurangkan separuh sesuatu, dan mengurangkan separuh lagi, dan lagi dan lagi.
Sudah tentu, ini bukan cara nombor terapung disimpan dalam ingatan (ia menggunakan tatatanda saintifik). Walau bagaimanapun, ia menggambarkan bahawa ralat ketepatan titik terapung binari cenderung timbul kerana nombor "dunia nyata" yang biasanya kita minati biasanya adalah kuasa sepuluh - tetapi itu hanya kerana kita menggunakan sistem penomboran perpuluhan hari ini - hari ini. Itulah sebabnya kami menyebut 71% dan bukannya "5 daripada setiap 7" (71% ialah anggaran kerana 5/7 tidak boleh diwakili dengan tepat oleh sebarang nombor perpuluhan).
Jadi tidak: nombor titik terapung binari tidak rosak, ia kebetulan tidak sempurna seperti sistem nombor berasaskan 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 kesaksamaan dengan perbandingan yang membolehkan tahap toleransi tertentu, yang bermaksud:
Jangan jangan buat
if (x == y) { ... }
Sebaliknya laksanakan
if (abs(x - y) .
Yang manakah
abs
是绝对值。myToleranceValue
perlu dipilih berdasarkan aplikasi khusus anda - ia mempunyai banyak kaitan dengan "bilik goyang" yang anda sediakan untuk membenarkan, dan kemungkinan jumlah terbesar yang anda bandingkan (disebabkan oleh isu kehilangan ketepatan) . Perhatikan pemalar gaya "epsilon" dalam bahasa pilihan anda. Ini boleh digunakan sebagai nilai toleransi, tetapi keberkesanannya bergantung pada saiz (saiz) nombor yang anda gunakan, kerana pengiraan pada nombor besar mungkin melebihi ambang epsilon.