วิเคราะห์
JavaScript มีหมายเลขประเภทตัวเลขเดียวและตัวเลขทั้งหมดใน JavaScript จะแสดงในรูปแบบมาตรฐาน IEEE-754 ปัญหาความแม่นยำของหมายเลขจุดลอยตัวนั้นไม่ได้เป็นเอกลักษณ์ของ JavaScript เนื่องจากทศนิยมบางตัวเป็นตัวเลขที่ไม่มีที่สิ้นสุดในไบนารี:
ทศนิยม
0.1 0.0001 1001 1001 1001 ...
0.2 0.0011 0011 0011 0011 ...
0.3 0.0100 1100 1100 1100 ...
0.4 0.0110 0110 0110 0110 ...
0.5 0.1
0.6 0.1001 1001 1001 1001 ...
ตัวอย่างเช่น 1.1 โปรแกรมของมันไม่สามารถเป็นตัวแทนของ '1.1' ได้ แต่สามารถบรรลุความแม่นยำในระดับหนึ่งเท่านั้น
1.09999999999999999999999999999999999
ปัญหาในจาวาสคริปต์มีความซับซ้อนมากขึ้นนี่เป็นเพียงข้อมูลการทดสอบบางอย่างใน Chrome:
อินพุตและเอาต์พุต
1.0-0.9 == 0.1 เท็จ
1.0-0.8 == 0.2 เท็จ
1.0-0.7 == 0.3 เท็จ
1.0-0.6 == 0.4 จริง
1.0-0.5 == 0.5 จริง
1.0-0.4 == 0.6 จริง
1.0-0.3 == 0.7 จริง
1.0-0.2 == 0.8 จริง
1.0-0.1 == 0.9 จริง
แก้ปัญหา
ดังนั้นจะหลีกเลี่ยงปัญหาที่ไม่ใช่โบกประเภทนี้ด้วย 1.0-0.9! = 0.1? นี่คือวิธีแก้ปัญหาที่ใช้บ่อยขึ้น
การคัดลอกรหัสมีดังนี้:
(1.0-0.9) .tofixed (ตัวเลข) // tofixed () พารามิเตอร์ความแม่นยำจะต้องอยู่ระหว่าง 0 ถึง 20
parsefloat ((1.0-0.9) .tofixed (10)) === 0.1 // ผลลัพธ์เป็นจริง
parsefloat ((1.0-0.8) .tofixed (10)) === 0.2 // ผลลัพธ์เป็นจริง
parsefloat ((1.0-0.7) .tofixed (10)) === 0.3 // ผลลัพธ์เป็นจริง
parsefloat ((11.0-11.8) .tofixed (10)) === -0.8 // ผลลัพธ์เป็นจริง
วิธีการกลั่น
การคัดลอกรหัสมีดังนี้:
// ใช้วิธีเครื่องมือ isequal เพื่อตรวจสอบว่าค่าเท่ากันหรือไม่
ฟังก์ชั่น isequal (number1, number2, ตัวเลข) {
Digits = Digits == ไม่ได้กำหนด?
ส่งคืน number1.tofixed (ตัวเลข) === number2.tofixed (ตัวเลข);
-
isequal (1.0-0.7, 0.3);
// วิธีการขยายแบบดั้งเดิมชอบสไตล์ที่มุ่งเน้นวัตถุ
number.prototype.isequal = function (หมายเลข, ตัวเลข) {
Digits = Digits == ไม่ได้กำหนด?
ส่งคืน this.tofixed (ตัวเลข) === number.tofixed (ตัวเลข);
-
(1.0-0.7) .Sequal (0.3);