มันแตกต่างกันอย่างไรเมื่อฉันใช้ชนิดข้อมูลทศนิยมและทศนิยมใน MySQL?
เมื่อใดที่ฉันควรใช้
มันแตกต่างกันอย่างไรเมื่อฉันใช้ชนิดข้อมูลทศนิยมและทศนิยมใน MySQL?
เมื่อใดที่ฉันควรใช้
คำตอบ:
นี่คือสิ่งที่ฉันพบเมื่อฉันมีข้อสงสัยนี้
mysql> create table numbers (a decimal(10,2), b float);
mysql> insert into numbers values (100, 100);
mysql> select @a := (a/3), @b := (b/3), @a * 3, @b * 3 from numbers \G
*************************** 1. row ***************************
@a := (a/3): 33.333333333
@b := (b/3): 33.333333333333
@a + @a + @a: 99.999999999000000000000000000000
@b + @b + @b: 100
ทศนิยมทำในสิ่งที่ควรทำในกรณีนี้มันตัดส่วนที่เหลือออกไปดังนั้นจึงสูญเสียส่วนที่ 1/3
ดังนั้นสำหรับผลรวมทศนิยมจะดีกว่า แต่สำหรับหน่วยงานลอยดีกว่าถึงจุดหนึ่งแน่นอน ฉันหมายถึงการใช้ DECIMAL จะไม่ทำให้คุณ "เลขคณิตพิสูจน์ล้มเหลว" ในวิธีใด ๆ
หวังว่านี่จะช่วยได้
@a
ให้ 99.999999999000000000000000000000000 ทศนิยมหรือไม่ ซึ่งเป็นเทคนิคที่ถูกต้อง
"ลอย" ในสภาพแวดล้อมส่วนใหญ่เป็นประเภททศนิยมจุดไบนารี สามารถจัดเก็บค่าฐาน -2 ได้อย่างแม่นยำ (จนถึงบางจุด) แต่ไม่สามารถจัดเก็บค่าฐาน 10 (ฐานสิบ) ได้อย่างแม่นยำ ทุ่นลอยที่เหมาะสมที่สุดสำหรับการคำนวณทางวิทยาศาสตร์ พวกมันไม่เหมาะกับคณิตศาสตร์เชิงธุรกิจส่วนใหญ่และการใช้ทุ่นอย่างไม่เหมาะสมจะกัดคุณ ค่าทศนิยมจำนวนมากไม่สามารถแสดงได้อย่างแน่นอนในฐาน -2 0.1
ไม่สามารถเช่นและเพื่อให้คุณเห็นผลแปลก ๆ 1.0 - 0.1 = 0.8999999
เช่น
ทศนิยมเก็บตัวเลขฐาน 10 ทศนิยมเป็นประเภทที่ดีสำหรับคณิตศาสตร์ธุรกิจส่วนใหญ่ (แต่ชนิดใด ๆ ของ "เงิน" ในตัวมีความเหมาะสมมากกว่าสำหรับการคำนวณทางการเงิน) ซึ่งช่วงของค่าเกินกว่าที่ระบุไว้ในประเภทจำนวนเต็มและจำเป็นต้องมีค่าเศษส่วน Decimals ตามชื่อหมายถึงถูกออกแบบมาสำหรับตัวเลขฐาน 10 ซึ่งสามารถจัดเก็บค่าทศนิยมได้อย่างถูกต้อง (อีกครั้งจนถึงจุดหนึ่ง)
MySQL เพิ่งเปลี่ยนวิธีที่พวกเขาพวกเขาเก็บประเภททศนิยม ในอดีตพวกเขาเก็บอักขระ (หรือ nybbles) สำหรับแต่ละหลักประกอบด้วยการแทน ASCII (หรือ nybble) ของตัวเลข - vs - จำนวนเต็มประกอบของสองหรือบางส่วนของอนุพันธ์
รูปแบบการจัดเก็บปัจจุบันสำหรับ DECIMAL คือชุดของจำนวนเต็ม 1,2,3 หรือ 4 ไบต์ซึ่งบิตถูกต่อกันเพื่อสร้างหมายเลขส่วนเติมเต็มของสองด้วยจุดทศนิยมโดยนัยที่คุณกำหนดและเก็บไว้ใน DB schema เมื่อคุณประกาศ คอลัมน์และระบุว่าเป็นขนาด DECIMAL และตำแหน่งจุดทศนิยม
ตัวอย่างเช่นถ้าคุณใช้ int แบบ 32 บิตคุณสามารถเก็บหมายเลขใด ๆ ได้ตั้งแต่ 0 - 4,294,967,295 นั่นจะครอบคลุม 999,999,999 อย่างน่าเชื่อถือดังนั้นถ้าคุณขว้าง 2 บิตและใช้ (1 << 30 -1) คุณจะไม่ยอมแพ้ การครอบคลุมตัวเลข 9 หลักทั้งหมดที่มีเพียง 4 ไบต์จะมีประสิทธิภาพมากกว่าการครอบคลุม 4 หลักใน 32 บิตโดยใช้อักขระ ASCII 4 ตัวหรือตัวเลข 8 nybble (nybble คือ 4 บิตอนุญาตให้มีค่า 0-15 มากกว่าที่จำเป็นสำหรับ 0-9 แต่คุณไม่สามารถกำจัดของเสียนั้นได้โดยไปที่ 3 บิตเนื่องจากครอบคลุมเฉพาะค่า 0-7)
ตัวอย่างที่ใช้ในเอกสารออนไลน์ MySQL ใช้ DECIMAL (18,9) เป็นตัวอย่าง นี่คือตัวเลข 9 หลักก่อนหน้าและ 9 หลักหลังจุดทศนิยมโดยนัยซึ่งตามที่อธิบายไว้ข้างต้นจำเป็นต้องใช้ที่เก็บข้อมูลต่อไปนี้
ในฐานะที่เป็น 18 ตัวอักษร 8 บิต: 144 บิต
ในฐานะที่เป็น 18 4 บิต nybbles: 72 บิต
ในฐานะที่เป็น 2 จำนวนเต็ม 32 บิต: 64 บิต
ปัจจุบัน DECIMAL รองรับได้สูงสุด 65 หลักเนื่องจาก DECIMAL (M, D) ซึ่งค่าที่ใหญ่ที่สุดสำหรับ M ที่อนุญาตคือ 65 และค่า D ที่อนุญาตสูงสุดคือ 30
เพื่อไม่ให้ต้องใช้จำนวน 9 หลักในแต่ละครั้งจำนวนเต็มที่น้อยกว่า 32 บิตจะถูกใช้เพื่อเพิ่มตัวเลขโดยใช้จำนวนเต็ม 1,2 และ 3 ไบต์ ด้วยเหตุผลบางอย่างที่ขัดแย้งกับลอจิกลงชื่อแทนที่จะใช้ ints ที่ไม่ได้ลงชื่อและใช้วิธีนี้ 1 บิตถูกโยนออกไปทำให้เกิดความสามารถในการจัดเก็บต่อไปนี้ สำหรับ 1,2 และ 4 ไบต์ ints บิตที่หายไปไม่สำคัญ แต่สำหรับ 3 ไบต์ของไบต์นั้นเป็นหายนะเพราะตัวเลขทั้งหมดหายไปเนื่องจากการสูญเสียบิตเดียวนั้น
ด้วย int 7 บิต: 0 - 99
ด้วย int 15 บิต: 0 - 9,999
ด้วย 23- บิต int: 0 - 999,999 (0 - 9,999,999 กับ 24- บิต int)
จำนวนเต็ม 1,2,3 และ 4 ไบต์ถูกรวมเข้าด้วยกันเพื่อสร้าง "bit pool" DECIMAL ใช้เพื่อแสดงตัวเลขอย่างแม่นยำว่าเป็นจำนวนเต็มส่วนเติมเต็มของทั้งสอง จุดทศนิยมจะไม่ถูกเก็บไว้โดยนัย
ซึ่งหมายความว่าไม่จำเป็นต้องใช้ ASCII ไปยังการแปลง int เพื่อให้เอ็นจิ้น DB แปลง "number" เป็นสิ่งที่ CPU จำได้ว่าเป็นตัวเลข ไม่มีการปัดเศษไม่มีข้อผิดพลาดในการแปลงเป็นจำนวนจริงที่ CPU สามารถจัดการได้
การคำนวณจำนวนเต็มขนาดใหญ่โดยพลการนี้จะต้องทำในซอฟต์แวร์เนื่องจากไม่มีการสนับสนุนฮาร์ดแวร์สำหรับหมายเลขชนิดนี้ แต่ไลบรารี่เหล่านี้เก่าและเหมาะสมที่สุดถูกเขียนขึ้นเมื่อ 50 ปีที่แล้วเพื่อรองรับข้อมูลจุดลอยตัวที่แม่นยำของ IBM 370 Fortran . พวกมันยังช้ากว่าพีชคณิตจำนวนเต็มคงที่ที่ทำกับฮาร์ดแวร์จำนวนเต็มของ CPU หรือการคำนวณจุดลอยตัวที่ทำใน FPU
ในแง่ของประสิทธิภาพการจัดเก็บเนื่องจากเลขชี้กำลังของการลอยถูกแนบกับการลอยแต่ละครั้งโดยระบุจุดโดยปริยายที่จุดทศนิยมเป็นมันซ้ำซ้อนอย่างหนาแน่นและดังนั้นจึงไม่มีประสิทธิภาพสำหรับการทำงานของ DB ในฐานข้อมูลคุณรู้อยู่แล้วว่าจุดทศนิยมอยู่ตรงไหนและทุกแถวในตารางที่มีค่าสำหรับคอลัมน์ DECIMAL นั้นต้องดูเฉพาะสเปคที่ 1 และเพียงตำแหน่งที่จะเก็บและจัดเก็บจุดทศนิยม ในสคีมาเป็นอาร์กิวเมนต์สำหรับ DECIMAL (M, D) เป็นความหมายของค่า M และ D
ข้อสังเกตมากมายที่พบที่นี่เกี่ยวกับรูปแบบที่จะใช้สำหรับแอพพลิเคชั่นประเภทต่างๆนั้นถูกต้องดังนั้นฉันจะไม่เชื่อประเด็นนั้น ฉันใช้เวลาในการเขียนที่นี่เพราะใครก็ตามที่รักษาเอกสารออนไลน์ของ MySQL ที่เชื่อมโยงไม่เข้าใจสิ่งใด ๆ ข้างต้นและหลังจากความพยายามที่น่าหงุดหงิดมากขึ้นที่จะอธิบายพวกเขาฉันก็ยอมแพ้ สิ่งบ่งชี้ที่ดีว่าพวกเขาเข้าใจได้ไม่ดีในสิ่งที่พวกเขาเขียนคือการนำเสนอเนื้อหาที่ยุ่งเหยิงและแทบจะอ่านไม่ออก
ตามความคิดสุดท้ายหากคุณต้องการการคำนวณจุดลอยตัวที่มีความแม่นยำสูงมีความก้าวหน้าอย่างมากในรหัสจุดลอยตัวในรอบ 20 ปีที่ผ่านมาและการสนับสนุนฮาร์ดแวร์สำหรับโฟลต 96 บิตและQuadruple Precisionนั้นอยู่ใกล้ ๆ แต่จะมีไลบรารี่ที่มีความแม่นยำตามอำเภอใจดีหากการจัดการค่าที่เก็บไว้นั้นมีความสำคัญ
ไม่เฉพาะเจาะจงกับ MySQL เท่านั้นความแตกต่างระหว่างประเภททศนิยมและทศนิยมเป็นวิธีที่พวกเขาแสดงค่าเศษส่วน {m*2^n | m, n Integers}
ลอยชนิดจุดแทนเศษส่วนในไบนารีซึ่งสามารถแสดงค่าเป็น ค่าเช่น 1/5 ไม่สามารถแสดงได้อย่างแม่นยำ (ไม่มีข้อผิดพลาดในการปัดเศษ) ตัวเลขทศนิยมจะถูก จำกัด ในทำนองเดียวกัน {m*10^n | m, n Integers}
แต่เป็นตัวแทนของตัวเลขเช่น ทศนิยมยังไม่สามารถแสดงตัวเลขได้เช่น 1/3 แต่บ่อยครั้งในหลาย ๆ เขตข้อมูลทั่วไปเช่นการเงินความคาดหวังก็คือเศษส่วนทศนิยมบางอย่างสามารถแสดงได้เสมอโดยไม่สูญเสียความน่าเชื่อถือ เนื่องจากตัวเลขทศนิยมสามารถแทนค่าเช่น$0.20
(หนึ่งในห้าของดอลลาร์) จึงเป็นที่ต้องการในสถานการณ์เหล่านั้น
ทศนิยมสำหรับปริมาณคงที่เช่นเงินที่คุณต้องการจำนวนทศนิยมเฉพาะ ทุ่นลอยสำหรับการจัดเก็บ ... ตัวเลขความแม่นยำจุดลอยตัว
ฉันพบว่ามีประโยชน์นี้:
โดยทั่วไปแล้วค่าโฟลตจะดีสำหรับการคำนวณทางวิทยาศาสตร์ แต่ไม่ควรใช้สำหรับค่าทางการเงิน / การเงิน สำหรับคณิตศาสตร์เชิงธุรกิจให้ใช้เลขฐานสิบเสมอ
ที่มา: http://code.rohitink.com/2013/06/12/mysql-integer-float-decimal-data-types-differences/
mysql> CREATE TABLE num(id int ,fl float,dc dec(5,2));
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO num VALUES(1,13.75,13.75);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO num VALUES(2,13.15,13.15);
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM num WHERE fl = 13.15;
Empty set (0.00 sec)
mysql> SELECT * FROM num WHERE dc = 13.15;
+------+-------+-------+
| id | fl | dc |
+------+-------+-------+
| 2 | 13.15 | 13.15 |
+------+-------+-------+
1 row in set (0.00 sec)
mysql> SELECT SUM(fl) ,SUM(dc) FROM num;
+--------------------+---------+
| SUM(fl) | SUM(dc) |
+--------------------+---------+
| 26.899999618530273 | 26.90 |
+--------------------+---------+
1 row in set (0.00 sec)
mysql> SELECT * FROM num WHERE ABS(fl - 13.15)<0.01;
+------+-------+-------+
| id | fl | dc |
+------+-------+-------+
| 2 | 13.15 | 13.15 |
+------+-------+-------+
1 row in set (0.00 sec)
หากคุณอยู่หลังการทำงานและไม่แม่นยำคุณควรทราบว่าการคำนวณด้วยการลอยนั้นเร็วกว่าทศนิยม
ประเภทจุดลอยตัว (ค่าโดยประมาณ) - ลอยสองเท่า
ชนิด FLOAT และ DOUBLE แสดงค่าข้อมูลตัวเลขโดยประมาณ MySQL ใช้สี่ไบต์สำหรับค่าความแม่นยำเดียวและแปดไบต์สำหรับค่าความแม่นยำสองเท่า
สำหรับ FLOAT มาตรฐาน SQL จะอนุญาตให้ใช้ข้อกำหนดทางเลือกของความแม่นยำ (แต่ไม่ใช่ช่วงของเลขชี้กำลัง) เป็นบิตตามด้วยคำสำคัญ FLOAT ในวงเล็บ MySQL ยังรองรับข้อกำหนดความแม่นยำที่เป็นตัวเลือกนี้ แต่ค่าความแม่นยำนั้นใช้เพื่อกำหนดขนาดการจัดเก็บเท่านั้น ความแม่นยำตั้งแต่ 0 ถึง 23 ผลลัพธ์ในคอลัมน์ FLOAT ความแม่นยำเดี่ยว 4 ไบต์ ความแม่นยำตั้งแต่ 24 ถึง 53 ส่งผลให้มีคอลัมน์ DOUBLE ที่มีความแม่นยำสองเท่า 8 ไบต์
MySQL อนุญาตให้ใช้ไวยากรณ์ที่ไม่เป็นมาตรฐาน: FLOAT (M, D) หรือ REAL (M, D) หรือความแม่นยำสองเท่า (M, D) ในที่นี้“ (M, D)” หมายถึงค่าที่สามารถจัดเก็บได้ด้วยจำนวน M ถึงทั้งหมดซึ่ง D หลักอาจอยู่หลังจุดทศนิยม ตัวอย่างเช่นคอลัมน์ที่กำหนดเป็น FLOAT (7,4) จะมีลักษณะเช่น -999.9999 เมื่อแสดง MySQL ทำการปัดเศษเมื่อเก็บค่าดังนั้นหากคุณแทรก 999.00009 ลงในคอลัมน์ FLOAT (7,4) ผลลัพธ์จะอยู่ที่ประมาณ 999.0001
เนื่องจากค่าจุดลอยตัวเป็นค่าประมาณและไม่ได้เก็บไว้เป็นค่าที่แน่นอนความพยายามที่จะปฏิบัติต่อพวกเขาอย่างแม่นยำในการเปรียบเทียบอาจนำไปสู่ปัญหา พวกเขายังขึ้นอยู่กับการพึ่งพาแพลตฟอร์มหรือการใช้งาน
เพื่อความสะดวกในการพกพาสูงสุดรหัสที่ต้องการจัดเก็บค่าข้อมูลตัวเลขโดยประมาณควรใช้ความแม่นยำแบบ FLOAT หรือ DOUBLE ที่ไม่มีข้อกำหนดของความแม่นยำหรือจำนวนหลัก
https://dev.mysql.com/doc/refman/5.5/en/floating-point-types.html
ปัญหาเกี่ยวกับค่า Floating-Point
จำนวนจุดลอยตัวบางครั้งทำให้เกิดความสับสนเพราะพวกเขาเป็นตัวอย่างและไม่ได้เก็บไว้เป็นค่าที่แน่นอน ค่า floating-point ตามที่เขียนในคำสั่ง SQL อาจไม่เหมือนกันกับค่าที่แสดงภายใน ความพยายามในการปฏิบัติต่อค่าจุดลอยตัวที่แน่นอนในการเปรียบเทียบอาจนำไปสู่ปัญหา พวกเขายังขึ้นอยู่กับการพึ่งพาแพลตฟอร์มหรือการใช้งาน ชนิดข้อมูล FLOAT และ DOUBLE อาจมีปัญหาเหล่านี้ สำหรับคอลัมน์ DECIMAL, MySQL ทำการดำเนินการด้วยความแม่นยำของตัวเลข 65 หลักซึ่งควรแก้ปัญหาความไม่ถูกต้องที่พบบ่อยที่สุด
ตัวอย่างต่อไปนี้ใช้ DOUBLE เพื่อแสดงให้เห็นว่าการคำนวณที่ดำเนินการโดยใช้การดำเนินการจุดลอยตัวนั้นอยู่ภายใต้ข้อผิดพลาดจุดลอย
mysql> CREATE TABLE t1 (i INT, d1 DOUBLE, d2 DOUBLE);
mysql> INSERT INTO t1 VALUES (1, 101.40, 21.40), (1, -80.00, 0.00),
-> (2, 0.00, 0.00), (2, -13.20, 0.00), (2, 59.60, 46.40),
-> (2, 30.40, 30.40), (3, 37.00, 7.40), (3, -29.60, 0.00),
-> (4, 60.00, 15.40), (4, -10.60, 0.00), (4, -34.00, 0.00),
-> (5, 33.00, 0.00), (5, -25.80, 0.00), (5, 0.00, 7.20),
-> (6, 0.00, 0.00), (6, -51.40, 0.00);
mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b
-> FROM t1 GROUP BY i HAVING a <> b;
+------+-------+------+
| i | a | b |
+------+-------+------+
| 1 | 21.4 | 21.4 |
| 2 | 76.8 | 76.8 |
| 3 | 7.4 | 7.4 |
| 4 | 15.4 | 15.4 |
| 5 | 7.2 | 7.2 |
| 6 | -51.4 | 0 |
+------+-------+------+
ผลลัพธ์ถูกต้อง แม้ว่าระเบียนห้ารายการแรกดูเหมือนว่าพวกเขาไม่ควรพอใจการเปรียบเทียบ (ค่าของ a และ b ไม่แตกต่างกัน) พวกเขาอาจทำเช่นนั้นเนื่องจากความแตกต่างระหว่างตัวเลขปรากฏรอบทศนิยมสิบหรือมากกว่านั้นขึ้นอยู่กับปัจจัย เช่นสถาปัตยกรรมคอมพิวเตอร์หรือรุ่นคอมไพเลอร์หรือระดับการเพิ่มประสิทธิภาพ ตัวอย่างเช่น CPU ที่แตกต่างกันอาจประเมินหมายเลขจุดลอยตัวที่แตกต่างกัน
หากคอลัมน์ d1 และ d2 ถูกกำหนดเป็น DECIMAL แทนที่จะเป็น DOUBLE ผลลัพธ์ของแบบสอบถาม SELECT จะมีเพียงหนึ่งแถวเท่านั้นซึ่งเป็นแถวสุดท้ายที่แสดงด้านบน
วิธีที่ถูกต้องในการทำการเปรียบเทียบจำนวนจุดลอยตัวคือการตัดสินใจเกี่ยวกับความคลาดเคลื่อนที่ยอมรับได้สำหรับความแตกต่างระหว่างตัวเลขจากนั้นทำการเปรียบเทียบกับค่าความคลาดเคลื่อน ตัวอย่างเช่นหากเรายอมรับว่าตัวเลขจุดลอยตัวควรได้รับการพิจารณาเหมือนกันหากตัวเลขเหล่านั้นเหมือนกันภายในความแม่นยำหนึ่งในหมื่น (0.0001) การเปรียบเทียบควรเขียนเพื่อค้นหาความแตกต่างที่ใหญ่กว่าค่าความอดทน:
mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b FROM t1
-> GROUP BY i HAVING ABS(a - b) > 0.0001;
+------+-------+------+
| i | a | b |
+------+-------+------+
| 6 | -51.4 | 0 |
+------+-------+------+
1 row in set (0.00 sec)
ในทางกลับกันเพื่อให้ได้แถวที่มีตัวเลขเหมือนกันการทดสอบควรค้นหาความแตกต่างภายในค่าความคลาดเคลื่อน:
mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b FROM t1
-> GROUP BY i HAVING ABS(a - b) <= 0.0001;
+------+------+------+
| i | a | b |
+------+------+------+
| 1 | 21.4 | 21.4 |
| 2 | 76.8 | 76.8 |
| 3 | 7.4 | 7.4 |
| 4 | 15.4 | 15.4 |
| 5 | 7.2 | 7.2 |
+------+------+------+
5 rows in set (0.03 sec)
ค่าจุดลอยตัวอาจขึ้นอยู่กับการพึ่งพาแพลตฟอร์มหรือการนำไปปฏิบัติ สมมติว่าคุณดำเนินการคำสั่งต่อไปนี้:
CREATE TABLE t1(c1 FLOAT(53,0), c2 FLOAT(53,0));
INSERT INTO t1 VALUES('1e+52','-1e+52');
SELECT * FROM t1;
ในบางแพลตฟอร์มคำสั่ง SELECT จะส่งกลับค่า inf และ -inf สำหรับคนอื่น ๆ มันจะส่งคืน 0 และ -0
ความหมายของปัญหาก่อนหน้านี้คือถ้าคุณพยายามสร้างสลาฟจำลองโดยการทิ้งเนื้อหาตารางด้วย mysqldump บนต้นแบบและโหลดไฟล์ดัมพ์ไปยังสเลฟอีกครั้งตารางที่มีคอลัมน์ลอยจุดอาจแตกต่างกันระหว่างโฮสต์ทั้งสอง
https://dev.mysql.com/doc/refman/5.5/en/problems-with-float.html
กฎฮาร์ด & เร็ว
หากสิ่งที่คุณต้องทำคือการเพิ่มลบหรือทวีคูณตัวเลขที่คุณเก็บไว้ DECIMAL นั้นดีที่สุด
หากคุณต้องการแบ่งหรือทำรูปแบบทางคณิตศาสตร์หรือพีชคณิตในรูปแบบอื่น ๆ กับข้อมูลที่คุณกำลังจะมีความสุขกับการลอย ไลบรารีจุดลอยตัวและตัวประมวลผลของ Intel ซึ่งเป็นหน่วยประมวลผลจุดลอยตัวนั้นมี TONs ของการดำเนินการเพื่อแก้ไขแก้ไขตรวจจับและจัดการพายุหิมะของข้อยกเว้นที่เกิดขึ้นเมื่อทำฟังก์ชันคณิตศาสตร์ทั่วไป - โดยเฉพาะอย่างยิ่งฟังก์ชันเหนือธรรมชาติ
สำหรับความถูกต้องฉันเคยเขียนระบบงบประมาณที่คำนวณ% การมีส่วนร่วมของบัญชี 3,000+ บัญชีสำหรับ 3,600 หน่วยต่อเดือนไปยังโหนดการรวมหน่วยของเดือนนั้นจากนั้นขึ้นอยู่กับเมทริกซ์ของเปอร์เซ็นต์ (3,000 + x 12 x 3,600) ฉันคูณจำนวนเงินที่งบประมาณโดยโหนดองค์กรสูงสุดลงไปอีก 3 ระดับถัดไปของโหนดองค์กรและคำนวณค่าทั้งหมด (3,000 +12) สำหรับหน่วยรายละเอียดทั้งหมด 3,200 หน่วยจากนั้น การคำนวณจุดลอยตัวที่มีความแม่นยำสองล้านล้านและล้านรายการใดรายการหนึ่งจะทำให้การประมาณการทั้งหมดเหล่านี้หมดไปในการรวมกลุ่มแบบกลุ่มย่อยกลับไปสู่ระดับสูงสุดในองค์กร
ข้อผิดพลาดที่จุดรวมลอยหลังจากทั้งหมดของการคำนวณนั้นคือZERO นั่นคือในปี 1986 และห้องสมุดจุดลอยตัวในวันนี้นั้นดีกว่าเมื่อก่อนมาก Intel ทำการคำนวณในระดับกลางทั้งหมดเป็นสองเท่าด้วยความแม่นยำ 80 บิตซึ่งทั้งหมดยกเว้นกำจัดข้อผิดพลาดในการปัดเศษ เมื่อมีคนบอกคุณว่า "มันเป็นข้อผิดพลาดของจุดลอยตัว" ก็เกือบจะไม่แน่นอน
float
(และdouble
) แสดงถึงเศษส่วนไบนารี
decimal
แทนเศษส่วนทศนิยม
declare @float as float(10)
declare @Decimal as decimal(10)
declare @Inetger as int
set @float =10.7
set @Decimal =10.7
set @Inetger=@Decimal
print @Inetger
ใน float เมื่อตั้งค่าเป็นจำนวนเต็มพิมพ์ 10 แต่ในทศนิยม 11
FLOAT(m,n)
มันนำไปสู่การปัดเศษสองรอบ มันไม่ได้ให้ประโยชน์อะไรเลย