เขียนด้วยคำพูดก่อนหน้านี้:
วันนี้ฉันช่วยเพื่อนร่วมงานของฉันแก้ปัญหาซึ่งก็คือมีทศนิยมมากมายที่ปรากฏขึ้นเมื่อทวีคูณทศนิยม ฉันเคยพบปัญหานี้มาก่อนดังนั้นฉันจะสรุปมันโดยเฉพาะ
ประเภทหมายเลข:
ประเภทตัวเลขเป็นประเภทที่ใช้กันมากที่สุดและน่าสนใจที่สุดใน eCmascript; ประเภทนี้ใช้รูปแบบ IEEE754 เพื่อแสดงจำนวนเต็มและค่าจุดลอยตัว (ค่าจุดลอยตัวเป็นค่าความแม่นยำสองเท่าในบางภาษา) เพื่อรองรับชนิดข้อมูลที่หลากหลาย ECMA-262 กำหนดรูปแบบพื้นผิวเชิงตัวเลขที่แตกต่างกัน
ทศนิยม:
var intnum = 10; //จำนวนเต็ม
Octal:
var octalnum1 = 070; // Octal 56
var octalnum2 = 079; // การแก้ไขค่าแปดเท่าที่ไม่ถูกต้องเป็น 79
ตัวอักษร Octal นั้นไม่ถูกต้องในโหมดที่เข้มงวด
Hexadecimal:
var hexnum1 = 0xa; // 10
โปรดจำไว้ว่า: เมื่อทำการดำเนินการค่าทั้งหมดที่แสดงใน octal และ hexadecimal ในที่สุดจะถูกแปลงเป็นทศนิยม;
เหตุใดการดำเนินการของทศนิยมจึงมีข้อผิดพลาด?
ความคืบหน้าสูงสุดของค่าจุดลอยตัวคือทศนิยม 17 หลัก แต่ความแม่นยำของมันน้อยกว่าของจำนวนเต็มเมื่อดำเนินการ จำนวนเต็มจะถูกแปลงเป็นทศนิยมเมื่อดำเนินการ และเมื่อคำนวณการดำเนินการทศนิยมใน Java และ JavaScript ทศนิยมทศนิยมจะถูกแปลงเป็นไบนารีที่สอดคล้องกันก่อนและทศนิยมบางส่วนไม่สามารถแปลงเป็นไบนารีได้อย่างสมบูรณ์ดังนั้นข้อผิดพลาดครั้งแรกจึงเกิดขึ้นที่นี่ หลังจากทศนิยมทั้งหมดจะถูกแปลงเป็นไบนารีแล้วการดำเนินการไบนารีจะดำเนินการเพื่อให้ได้ผลลัพธ์ไบนารี จากนั้นแปลงผลลัพธ์ไบนารีเป็นทศนิยมและข้อผิดพลาดที่สองมักจะเกิดขึ้นที่นี่
ดังนั้น (0.1+0.2)! = 03
สารละลาย:
รหัสโปรแกรม
ฟังก์ชั่นการหารเพื่อรับผลการแบ่งที่ถูกต้อง
หมายเหตุ: จะมีข้อผิดพลาดในผลการแบ่งของ JavaScript ซึ่งจะชัดเจนมากขึ้นเมื่อหารหมายเลขลอยสองจุด ฟังก์ชั่นนี้ส่งคืนผลการแบ่งที่แม่นยำยิ่งขึ้น
โทร: accdiv (arg1, arg2)
ค่าส่งคืน: ผลลัพธ์ที่แน่นอนของ Arg1 หารด้วย arg2
ฟังก์ชั่น accdiv (arg1, arg2) {var t1 = 0, t2 = 0, r1, r2; ลอง {t1 = arg1.toString (). แยก (".") [1] .length} catch (e) {} ลอง {t2 = arg2.toString (). แยก (".") [1]. ความยาว} จับ (e) {} ด้วย (คณิตศาสตร์) {r1 = number (arg1.tostring r2 = number (arg2.toString (). แทนที่ (".", ")) return (r1/r2)*pow (10, t2-t1);}}การเพิ่มวิธี DIV ในประเภทหมายเลขนั้นสะดวกกว่าในการโทร
number.prototype.div = function (arg) {return accdiv (this, arg); -ฟังก์ชั่นการคูณเพื่อให้ได้ผลลัพธ์การคูณที่แม่นยำ
หมายเหตุ: จะมีข้อผิดพลาดในผลการคูณของ JavaScript ซึ่งจะชัดเจนมากขึ้นเมื่อคูณสองจุดลอยตัว ฟังก์ชั่นนี้ส่งคืนผลลัพธ์การคูณที่แม่นยำยิ่งขึ้น
โทร: Accmul (Arg1, Arg2)
ค่าส่งคืน: ผลลัพธ์ที่แน่นอนของ Arg1 คูณด้วย arg2
ฟังก์ชั่น accmul (arg1, arg2) {var m = 0, s1 = arg1.toString (), s2 = arg2.toString (); ลอง {m+= s1.split (".") [1] .length} catch (e) {} ลอง {m+= s2.split (".") [1] .length} catch (e) {} หมายเลขคืน (s1.replace (",", ")*)การเพิ่มวิธี MUL ลงในประเภทหมายเลขนั้นสะดวกกว่าในการโทร
number.prototype.mul = function (arg) {return accmul (arg, this);}ฟังก์ชั่นเพิ่มเติมเพื่อให้ได้ผลลัพธ์นอกจากนี้
หมายเหตุ: จะมีข้อผิดพลาดในผลการเพิ่มของ JavaScript ซึ่งจะชัดเจนมากขึ้นเมื่อเพิ่มหมายเลขจุดลอยตัวสองจุด ฟังก์ชั่นนี้ส่งคืนผลลัพธ์การเพิ่มที่แม่นยำยิ่งขึ้น
โทร: Accadd (Arg1, Arg2)
ค่าส่งคืน: ผลลัพธ์ที่แน่นอนของ Arg1 plus arg2
Function Acadd (Arg1, Arg2) {var r1, r2, m; ลอง {r1 = arg1.toString (). split (".") [1] .length} catch (e) {r1 = 0} ลอง {r2 = arg2.toString (). แยก (".") [1] .length (arg1*m+arg2*m)/m}เพิ่มวิธีการเพิ่มในประเภทตัวเลขทำให้การโทรสะดวกยิ่งขึ้น
number.prototype.add = function (arg) {return accadd (arg, this);}รวมฟังก์ชั่นเหล่านี้ที่คุณต้องการใช้แล้วเรียกมันเพื่อคำนวณ
ตัวอย่างเช่นหากคุณต้องการคำนวณ: 7*0.8 จากนั้นเปลี่ยนเป็น (7) .mul (8)
การดำเนินการอื่น ๆ มีความคล้ายคลึงกันและผลลัพธ์ที่แม่นยำยิ่งขึ้นสามารถรับได้
วิธีแก้ปัญหา 2:
วิธีการที่ใช้กันทั่วไปมากขึ้นคือวิธี tofixed () และ tofixed () สามารถปัดหมายเลขเป็นตัวเลขที่มีหมายเลขทศนิยมที่ระบุ การเพิ่มวิธีนี้หลังจากผลการคำนวณของเราก็โอเค แต่มันจะมีผลกระทบเล็กน้อยต่อความแม่นยำ หากข้อกำหนดความถูกต้องไม่สูงขอแนะนำให้ใช้