คำตอบสำหรับเรื่องนี้คือ "น่าประหลาดใจ" ง่าย ๆ :
เฟิร์ส - เป็นส่วนใหญ่ของคุณอาจจะรู้ - ช่วง 32 บิตจำนวนเต็มจาก-2147483648เพื่อ2,147,483,647 แล้วจะเกิดอะไรขึ้นถ้า PHP ได้ผลลัพธ์นั่นคือสิ่งที่ใหญ่กว่านี้?
โดยปกติแล้วจะคาดหวังว่า "ล้น" ทันทีที่ก่อให้เกิด2,147,483,647 + 1จะกลายเป็น-2147483648 อย่างไรก็ตามนั่นไม่ใช่กรณี ถ้า PHP พบจำนวนที่มากกว่าจะส่งคืน FLOAT แทน INT
ถ้า PHP พบจำนวนเกินขอบเขตของประเภทจำนวนเต็มมันจะถูกตีความว่าเป็นลอยแทน นอกจากนี้การดำเนินการที่ส่งผลให้จำนวนเกินขอบเขตของประเภทจำนวนเต็มจะส่งกลับลอยแทน
http://php.net/manual/en/language.types.integer.php
สิ่งนี้กล่าวและรู้ว่าการใช้งาน PHP FLOAT นั้นเป็นไปตามรูปแบบความแม่นยำสองเท่าของ IEEE 754 หมายความว่า PHP สามารถจัดการกับตัวเลขได้มากถึง 52 บิตโดยไม่ต้องลดความแม่นยำลง (บนระบบ 32 บิต)
ดังนั้น ณ จุดที่ผลรวมของคุณไปถึง9,007,199,254,740,992 (ซึ่งก็คือ2 ^ 53 ) ค่า Float ที่ส่งคืนโดย PHP Maths จะไม่แม่นยำพออีกต่อไป
E:\PHP>php -r "$x=bindec(\"100000000000000000000000000000000000000000000000000000\"); echo number_format($x,0);"
9.007.199.254.740.992
E:\PHP>php -r "$x=bindec(\"100000000000000000000000000000000000000000000000000001\"); echo number_format($x,0);"
9.007.199.254.740.992
E:\PHP>php -r "$x=bindec(\"100000000000000000000000000000000000000000000000000010\"); echo number_format($x,0);"
9.007.199.254.740.994
ตัวอย่างนี้แสดงให้เห็นถึงจุดที่ PHP มีความแม่นยำลดลง อันดับแรกบิตบิตสุดท้ายจะลดลงทำให้การแสดงออก 2 ครั้งแรกส่งผลให้มีจำนวนเท่ากัน - ซึ่งไม่ใช่
จากนี้ไปคณิตศาสตร์จะผิดทั้งหมดเมื่อทำงานกับชนิดข้อมูลเริ่มต้น
•มันเป็นปัญหาเดียวกันสำหรับภาษาที่ตีความอื่น ๆ เช่น Python หรือ Perl หรือไม่?
ฉันไม่คิดอย่างนั้น ฉันคิดว่านี่เป็นปัญหาของภาษาที่ไม่มีความปลอดภัยประเภท ในขณะที่จำนวนเต็มจำนวนเต็มดังที่กล่าวข้างต้นจะเกิดขึ้นในทุกภาษาที่ใช้ชนิดข้อมูลคงที่ภาษาที่ไม่มีความปลอดภัยของประเภทอาจพยายามจับกับประเภทข้อมูลอื่น ๆ อย่างไรก็ตามเมื่อพวกเขาชนชายแดน "ตามธรรมชาติ" (กำหนดโดยระบบ) พวกเขาอาจส่งคืนสิ่งใดก็ได้ แต่ผลลัพธ์ที่ถูกต้อง
อย่างไรก็ตามแต่ละภาษาอาจมีเธรดต่างกันสำหรับสถานการณ์ดังกล่าว