Rumah >hujung hadapan web >tutorial js >Mengapa js tidak boleh mengendalikan operasi perpuluhan dengan betul? _kemahiran javascript
var sum = 0; for(var i = 0; i < 10; i++) { sum += 0.1; } console.log(sum);
Adakah program di atas akan mengeluarkan 1?
Dalam artikel 25 soalan temuduga JavaScript yang perlu anda ketahui , soalan ke-8 menerangkan secara ringkas mengapa js tidak dapat mengendalikan operasi perpuluhan dengan betul. Hari ini saya akan melihat semula topik lama dan menganalisis isu ini dengan lebih mendalam.
Tetapi pertama sekali, perlu diingatkan bahawa ketidakupayaan untuk mengendalikan operasi perpuluhan dengan betul bukanlah ralat reka bentuk dalam bahasa JavaScript itu sendiri, bahasa pengaturcaraan peringkat tinggi lain, seperti C, Java, dll., juga tidak dapat untuk mengendalikan operasi perpuluhan dengan betul:
#include <stdio.h> void main(){ float sum; int i; sum = 0; for(i = 0; i < 100; i++) { sum += 0.1; } printf('%f\n', sum); //10.000002 }
Perwakilan nombor di dalam komputer
Kita semua tahu bahawa program yang ditulis dalam bahasa pengaturcaraan peringkat tinggi perlu ditukar kepada bahasa mesin yang boleh dikenali oleh CPU (Unit Pemprosesan Pusat) melalui tafsiran, penyusunan dan operasi lain sebelum ia boleh dijalankan , untuk CPU, ia tidak mengenali sistem perpuluhan dan perpuluhan nombor Oktal dan heksadesimal, dsb., nombor asas yang kami isytiharkan dalam program ini akan ditukar kepada nombor binari untuk pengiraan.
Mengapa tidak menukarnya kepada nombor terner untuk pengiraan?
Bagian dalam komputer terdiri daripada banyak komponen elektronik seperti IC (Litar Bersepadu: Litar Bersepadu Ia kelihatan seperti ini:
).IC datang dalam pelbagai bentuk, dengan banyak pin disusun bersebelahan di kedua-dua belah atau di dalam mereka (hanya satu sisi ditunjukkan dalam gambar). Semua pin IC hanya mempunyai dua keadaan voltan DC 0V atau 5V, iaitu satu pin IC hanya boleh mewakili dua keadaan. Ciri IC ini menentukan bahawa data di dalam komputer hanya boleh diproses dengan nombor binari.
Oleh kerana 1 bit (satu pin) hanya boleh mewakili dua keadaan, kaedah pengiraan binari menjadi 0, 1, 10, 11, 100... Borang ini:
Jadi, dalam operasi nombor, semua operan akan ditukar kepada nombor perduaan untuk mengambil bahagian dalam operasi, seperti 39, akan ditukar kepada perduaan 00100111
Perwakilan binari perpuluhan
Seperti yang dinyatakan di atas, data dalam program akan ditukar kepada nombor perduaan Apabila perpuluhan terlibat dalam operasi, ia juga akan ditukar kepada nombor perduaan Sebagai contoh, perpuluhan 11.1875 akan ditukar kepada 1101.0010.
Julat berangka yang dinyatakan oleh 4 digit selepas titik perpuluhan dalam nombor perduaan ialah 0.0000~0.1111 Oleh itu, ini hanya boleh mewakili gabungan (penambahan) empat nombor perpuluhan 0.5, 0.25, 0.125, 0.0625 dan pemberat bit selepas. titik perpuluhan:
Seperti yang dapat dilihat dari jadual di atas, digit seterusnya bagi nombor perpuluhan 0 ialah 0.0625 Oleh itu, perpuluhan antara 0 dan 0.0625 tidak boleh diwakili oleh nombor perduaan dengan 4 digit selepas titik perpuluhan jika anda menambah nombor perduaan selepas titik perpuluhan, Bilangan digit perpuluhan yang sepadan juga akan meningkat, tetapi tidak kira berapa banyak digit yang ditambah, keputusan 0.1 tidak boleh diperolehi. Malah, 0.1 ditukar kepada binari ialah 0.00110011001100110011... Ambil perhatian bahawa 0011 diulang tanpa terhingga:
console.log(0.2+0.1); //操作数的二进制表示 0.1 => 0.0001 1001 1001 1001…(无限循环) 0.2 => 0.0011 0011 0011 0011…(无限循环)
Jenis Nombor js tidak dibahagikan kepada integer, ketepatan tunggal, ketepatan berganda, dsb. seperti C/Java, tetapi dinyatakan secara seragam sebagai jenis titik terapung berketepatan ganda. Menurut peraturan IEEE, nombor titik terapung ketepatan tunggal menggunakan 32 bit untuk mewakili semua perpuluhan, manakala nombor titik terapung ketepatan dua menggunakan 64 bit untuk mewakili semua nombor titik terapung terdiri daripada tanda, mantissa, eksponen dan asas , jadi tidak semua digit digunakan Untuk mewakili perpuluhan, simbol, eksponen, dsb. juga mesti menduduki digit dan asas tidak menduduki digit:
Bahagian perpuluhan nombor titik terapung berketepatan dua menyokong sehingga 52 digit, jadi selepas menambah kedua-duanya, anda mendapat rentetan 0.0100110011001100110011001100110011001100...nombor perduaan yang dipotong kerana had perpuluhan nombor titik terapung Pada masa ini, tukarkannya kepada perpuluhan, Itu menjadi 0.30000000000000004.
Ringkasan
js tidak boleh mengendalikan operasi perpuluhan dengan betul, termasuk bahasa pengaturcaraan peringkat tinggi yang lain Ini bukan ralat reka bentuk bahasa itu sendiri, tetapi komputer itu sendiri tidak boleh mengendalikan operasi perpuluhan dengan betul kerana tidak semua pecahan perpuluhan boleh diwakili dalam perduaan.
Di atas adalah keseluruhan kandungan artikel ini, saya harap ia akan membantu kajian semua orang.