Sudah ada beberapa artikel tentang Habré (
satu ,
dua ,
dua dan setengah ) yang ditujukan untuk format floating point Posit baru, penulis yang menyajikannya sebagai yang lebih unggul dari standar IEEE 754 float dalam segala hal. Format baru ini juga menemukan kritik (
satu ,
dua ) yang mengklaim bahwa kelemahan Posit lebih besar daripada kelebihannya. Tetapi bagaimana jika kita benar-benar memiliki format revolusioner baru, dan kritik itu hanya disebabkan oleh kecemburuan dan ketidakmampuan orang-orang yang mengkritik? Nah, cara terbaik untuk mengetahuinya adalah dengan mengambil dan menghitung sendiri.
Pendahuluan
Kelebihan dari format baru ditunjukkan oleh contoh-contoh sederhana dengan penambahan / penggandaan angka dari urutan yang sama, yang menghasilkan akurasi satu atau dua digit lebih tinggi. Namun, dalam perhitungan nyata, plus / minus satu bit kesalahan operasi tunggal tidak masalah, karena kami menghitungnya dengan akurasi terbatas.
Akumulasi kesalahan sebagai hasil dari urutan operasi adalah penting, ketika setelah beberapa waktu kesalahan dalam digit yang lebih rendah mulai mengarah pada kesalahan yang lebih lama. Inilah yang akan kami coba alami.
Persiapan
Untuk pengujian, saya mengambil implementasi Posit dengan judul pathos
dari sini . Untuk mengkompilasinya di Visual Studio, kami harus menambahkan baris #define CLZ (n) __lzcnt (n) dalam file util.h dan mengganti 0.f / 0.f dalam file posit.cpp dengan std :: numeric_limits <float> :: quiet_NaN (). By the way, implementasi untuk fungsi matematika dasar (baik, kecuali untuk root) juga tidak ditemukan di perpustakaan ini - ini adalah alasan lain untuk mencurigai ada sesuatu yang salah.
Uji 1. Penggandaan bilangan kompleks
Transformasi Fourier, dihitung menggunakan aritmatika kompleks, digunakan sedapat mungkin. Pada awalnya, saya ingin menguji Posit pada transformasi Fourier; tetapi karena akurasinya sangat tergantung pada implementasi, untuk pengujian yang benar Anda harus mempertimbangkan semua algoritma dasar, yang agak memakan waktu; oleh karena itu, Anda dapat memulai dengan operasi yang lebih sederhana - penggandaan bilangan kompleks.
Jika kita mengambil vektor tertentu dan memutarnya 360 kali 1 °, maka pada akhirnya kita akan mendapatkan vektor asli yang sama. Bahkan, hasilnya akan sedikit berbeda karena akumulasi kesalahan - dan semakin besar jumlah belokan, semakin besar kesalahannya. Jadi, gunakan kode sederhana ini
complex<T> rot(cos(a), sin(a)); complex<T> vec(length, 0); for (long i = 0; i < count; i++) { vec *= rot; } cout << "error: " << stdev(vec.real() - length, vec.imag()) << endl;
kami memutar vektor dengan berbagai jenis data, dan kami akan menganggap kesalahan sebagai penyimpangan kuadrat dari vektor yang dihasilkan dari aslinya (yang juga dapat diartikan sebagai panjang vektor perbedaan).
Pertama, ambil vektor satuan sebagai yang paling mendukung Posit:
Belum ada pemimpin yang jelas di sini - keuntungannya dua kali lipat dari yang satu atau yang lain. Tambah panjang vektor yang diputar ke 1000:
Nilai kesalahan hampir sama. Silakan - 1.000.000:
Di sini Posit sudah percaya diri tertinggal, dan kesalahan ganda mulai merayap ke float. Mari kita mengambil waktu yang lebih lama lagi - 10
10 untuk sepenuhnya menghargai keunggulan format floating-point:
Di sini hal yang paling menarik di awal, di 4 iterasi - ketika float memberikan kesalahan sepadan dengan double, dan Posit sudah memiliki hasil yang sepenuhnya salah.
Tes 2. Perhitungan polinomial rasional
Karena tidak ada fungsi matematika di perpustakaan asli, kami akan mencoba melakukan sesuatu sendiri. Banyak fungsi yang kurang didekati dengan ekspansi dalam deret Taylor, dan lebih mudah untuk dihitung melalui aproksimasi oleh polinomial rasional. Perkiraan ini dapat diperoleh dengan berbagai cara, termasuk murni analitis - melalui pendekatan
Padé . Kami akan mengambilnya untuk pengujian, apalagi, dengan koefisien yang cukup besar sehingga mereka juga menjalani pembulatan sebelum perhitungan.
Menggunakan Wolfram Mathematica dan perintah PadeApproximant [Sin [x], {x, 0, {11, 11}}]
kami mendapatkan polinomial rasional untuk mendekati sinus, yang menyediakan akurasi ganda dalam kisaran dari sekitar -2 hingga 2:
Skema Horner biasanya digunakan langsung untuk perhitungan untuk menghemat perhitungan. Dalam kasus kami (menggunakan HornerForm) akan terlihat seperti
template< typename T > T padesin(T x) { T xx = x*x; return (x*(T(363275871831577908403200.) + xx*(-T(54839355237791393068800.) + xx*(T(2120649063015013090560.) + xx*(-T(31712777908498486800.) + xx*(T(203385425766914820.) - T(481959816488503.) * xx)))))) / (T(363275871831577908403200.) + xx*(T(5706623400804924998400.) + xx*(T(44454031219351353600.) + xx* (T(219578286347980560.) + xx*(T(707177798947620.) + T(1230626892363.) * xx))))); }
Mari kita lihat:
Seperti yang Anda lihat, situasi dengan Posit di sini terlihat menyedihkan - hampir tidak ada dua angka penting yang diputar.
Kesimpulan
Sayangnya, keajaiban tidak terjadi dan revolusi dibatalkan. Keuntungan Posit yang ditunjukkan pada perhitungan tunggal tidak lebih dari sebuah trik, harga yang merupakan penurunan akurat dalam akurasi dalam perhitungan nyata "berat". Satu-satunya alasan masuk akal untuk menggunakan Posit daripada IEEE 754 float atau titik tetap adalah alasan agama. Dengan menggunakan format ajaib, keakuratan yang dipastikan oleh iman suci penciptanya, dapat membawa banyak keajaiban ke program Anda!
Kode sumber PS
untuk verifikasi dan kritik .
PPS
Lanjutan .