Sự khác biệt giữa kiểu dữ liệu float và thập phân


175

Nó có gì khác biệt khi tôi sử dụng kiểu dữ liệu thập phân và số thập phân trong MySQL?.

Khi nào nên sử dụng?


Đừng sử dụng FLOAT(m,n), nó dẫn đến hai vòng; Trong khi đó, nó không cung cấp bất cứ thứ gì sử dụng.
Rick James

Câu trả lời:


185

Đây là những gì tôi tìm thấy khi tôi có nghi ngờ này.

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

Số thập phân đã làm chính xác những gì phải làm trong trường hợp này, nó cắt ngắn phần còn lại, do đó mất phần 1/3.

Vì vậy, đối với các khoản tiền thập phân là tốt hơn, nhưng đối với sự phân chia thì float là tốt hơn, đến một lúc nào đó, tất nhiên. Ý tôi là, sử dụng DECIMAL sẽ không cung cấp cho bạn "số học bằng chứng không thành công" trong bất kỳ phương tiện nào.

Hi vọng điêu nay co ich.


4
Một bài kiểm tra xuất sắc. Nhiều năm trước, các hàm chuyển đổi dữ liệu của C lib thường sẽ tạo ra hàng tấn sự khác biệt nhỏ trong các giá trị được chuyển đổi từ ASCII để nổi khi so sánh với các hàm trong SQLServer. Điều này hiếm khi đúng nữa. Kiểm tra là chính sách tốt nhất, vì tốt nhất nên biết chắc chắn sự đánh đổi là gì.

15
Trên thực tế, việc bổ sung DECIMAL là do lỗi. Nếu bạn thêm 33.333333333 ba lần, bạn sẽ không nhận được 100. Nếu bạn chia 100 cho 3, bạn sẽ không nhận được một số hữu tỷ mà không có một bộ chữ số lặp lại, vì vậy bạn không thể nhân nó với 3 và nhận được 100. Hãy ra ngoài một máy tính và thử nó. Về mặt logic, chúng ta biết 1/3 + 1/3 + 1/3 nên bằng 3/3 IE: 1, nhưng lớp số hữu tỷ này không cho phép chúng ta làm điều này. Câu trả lời thả nổi là đúng, nhưng kế toán của bạn sẽ ghét nó !
dùng2548100

5
Không @ađưa ra 99.999999999000000000000000000000 KHAI THÁC? Đó là kỹ thuật chính xác.
Vincent Poirier

78

"Phao" trong hầu hết các môi trường là loại dấu phẩy động nhị phân. Nó có thể lưu trữ chính xác các giá trị cơ sở 2 (đến một điểm nhất định), nhưng không thể lưu trữ chính xác nhiều giá trị cơ bản 10 (thập phân). Phao là thích hợp nhất cho các tính toán khoa học. Chúng không phù hợp với hầu hết các môn toán định hướng kinh doanh và việc sử dụng phao không phù hợp sẽ cắn bạn. Nhiều giá trị thập phân không thể được biểu diễn chính xác trong cơ sở 2. 0.1không thể, ví dụ, và vì vậy bạn thấy kết quả lạ như thế nào 1.0 - 0.1 = 0.8999999.

Số thập phân lưu trữ cơ sở 10 số. Thập phân là một loại tốt cho hầu hết các phép toán kinh doanh (nhưng bất kỳ loại "tiền" tích hợp nào phù hợp hơn cho các tính toán tài chính), trong đó phạm vi của các giá trị vượt quá mức được cung cấp bởi các loại số nguyên và các giá trị phân số là cần thiết. Số thập phân, như tên ngụ ý, được thiết kế cho các số cơ sở 10 - chúng có thể lưu trữ chính xác các giá trị thập phân (một lần nữa, đến một điểm nhất định).


@Michael Petrotta - người dùng chỉ cần nhập số thập phân của mình vào trường được cung cấp dưới dạng .. tôi cần lưu trữ chúng trong DB. cái nào sẽ phù hợp hơn ?
Hacker

12
@Pradeep: Tôi cảm thấy rằng bạn không trả lời câu hỏi của tôi. Đó có thể là do bạn không biết câu trả lời cho mình - có thể bạn không cảm thấy thoải mái khi hỏi người quản lý hoặc khách hàng của mình để biết thêm chi tiết. Nếu đó là trường hợp, tôi khuyên bạn nên cắn viên đạn, ngồi xuống với họ trong vài giờ và thực sự xem qua ứng dụng của bạn. Có gì chính xác , và trong rất chi tiết , là dữ liệu của bạn được sử dụng cho?
Michael Petrotta

1
Trên thực tế, hiện tại cả float và DECIMAL đều lưu trữ số của chúng theo cùng một cách. Sự khác biệt là cách những con số đó được sử dụng. DECIMAL sử dụng tất cả các bit để bao gồm một số nguyên bổ sung của hai, với một dấu thập phân ngụ ý. Một float có hai số nguyên và một số tăng cho một số khác. Cả cơ sở và số mũ đều là hai số nguyên bổ sung.
dùng2548100

1
Tôi nghĩ rằng câu trả lời của bạn có thể đúng về mặt kỹ thuật, nhưng sự nhấn mạnh vào float là loại nhị phân che khuất điểm cả hai đều lưu trữ dữ liệu của họ ở cùng định dạng. Một số dấu phẩy động được nâng lên lũy thừa đầu tiên là một số nguyên và được lưu trữ chính xác theo cách đó. Trong thực tế, đối với float chính xác 80 bit, cơ sở là một int64. Ngược lại, nếu bạn đã viết một thư viện cho các số nguyên nâng chúng lên quyền hạn, bạn sẽ gặp các vấn đề tương tự với các số nguyên, hoặc số thập phân, hoặc số La Mã hoặc kẹo mút. Đây không phải là bộ lưu trữ đang tạo ra "lỗi làm tròn", đó là cách xử lý toán học của thư viện.
dùng2548100

1
Với chất lượng rất kém của câu hỏi, trong đó hầu như không có thông số nào được đưa ra để chỉ ra các lĩnh vực quan tâm của OP là gì, thật khó để biết đâu là câu trả lời thích hợp. Nói chung, DECIMAL sẽ lưu trữ số lượng lớn hơn và các lib toán học đáp ứng mong đợi của kế toán viên, trong khi float kép là phương tiện lưu trữ kém hiệu quả hơn, tối ưu hóa các lib toán học - đáp ứng các nhà khoa học và tài chính (không phải kế toán viên) kỳ vọng tốt hơn nhiều.
dùng2548100

21

MySQL gần đây đã thay đổi cách họ lưu trữ loại DECIMAL . Trước đây, họ đã lưu trữ các ký tự (hoặc nybble) cho mỗi chữ số bao gồm một đại diện ASCII (hoặc nybble) của một số - so với - một số nguyên bổ sung hai hoặc một số đạo hàm của chúng.

Định dạng lưu trữ hiện tại cho DECIMAL là một chuỗi các số nguyên 1,2,3 hoặc 4 byte có các bit được nối để tạo số bù hai với một dấu thập phân ngụ ý, được xác định bởi bạn và được lưu trữ trong lược đồ DB khi bạn khai báo cột và chỉ định kích thước DECIMAL và vị trí dấu thập phân của nó.

Ví dụ, nếu bạn lấy int 32 bit, bạn có thể lưu trữ bất kỳ số nào từ 0 - 4.294.967.295. Điều đó sẽ chỉ đáng tin cậy bao gồm 999.999.999, vì vậy nếu bạn đã ném ra 2 bit và sử dụng (1 << 30 -1) thì bạn sẽ không từ bỏ. Bao gồm tất cả các số có 9 chữ số chỉ có 4 byte sẽ hiệu quả hơn so với việc bao gồm 4 chữ số trong 32 bit bằng 4 ký tự ASCII hoặc 8 chữ số nybble. (một nybble là 4 bit, cho phép các giá trị 0-15, nhiều hơn mức cần thiết cho 0-9, nhưng bạn không thể loại bỏ sự lãng phí đó bằng cách chuyển đến 3 bit, vì chỉ bao gồm các giá trị 0-7)

Ví dụ được sử dụng trên các tài liệu trực tuyến của MySQL sử dụng DECIMAL (18,9) làm ví dụ. Đây là 9 chữ số trước và 9 chữ số phía sau dấu thập phân ngụ ý, như đã giải thích ở trên yêu cầu lưu trữ sau.

Như 18 ký tự 8 bit: 144 bit

Như 18 nybble 4 bit: 72 bit

Như 2 số nguyên 32 bit: 64 bit

Hiện tại, DECIMAL hỗ trợ tối đa 65 chữ số, vì DECIMAL (M, D) trong đó giá trị lớn nhất cho M được phép là 65 và giá trị lớn nhất của D được phép là 30.

Vì vậy, để không yêu cầu các khối 9 chữ số cùng một lúc, các số nguyên nhỏ hơn 32 bit được sử dụng để thêm các chữ số sử dụng số nguyên 1,2 và 3 byte. Vì một số lý do bất chấp logic, đã ký, thay vì ints không dấu được sử dụng và làm như vậy, 1 bit bị loại bỏ, dẫn đến các khả năng lưu trữ sau. Đối với int int 1,2 và 4 byte, bit bị mất không thành vấn đề, nhưng đối với int 3 byte thì đó là một thảm họa vì toàn bộ một chữ số bị mất do mất bit đơn lẻ đó.

Với int 7 bit: 0 - 99

Với int 15 bit: 0 - 9,999

Với int 23 bit: 0 - 999.999 (0 - 9,999.999 với int 24 bit)

Các số nguyên 1,2,3 và 4 byte được nối với nhau để tạo thành một "nhóm bit" DECIMAL sử dụng để biểu diễn số chính xác như một số nguyên bổ sung của hai. Dấu thập phân KHÔNG được lưu trữ, nó được ngụ ý.

Điều này có nghĩa là không yêu cầu chuyển đổi ASCII sang int của công cụ DB để chuyển đổi "số" thành thứ mà CPU nhận ra là số. Không làm tròn, không có lỗi chuyển đổi, đó là con số thực mà CPU có thể thao tác.

Các tính toán trên số nguyên lớn tùy ý này phải được thực hiện trong phần mềm, vì không có phần cứng hỗ trợ cho loại số này, nhưng các thư viện này rất cũ và được tối ưu hóa cao, đã được viết cách đây 50 năm để hỗ trợ dữ liệu điểm nổi chính xác tùy ý của IBM 370 Fortran . Chúng vẫn chậm hơn rất nhiều so với đại số nguyên có kích thước cố định được thực hiện với phần cứng số nguyên CPU hoặc các phép tính dấu phẩy động được thực hiện trên FPU.

Về hiệu quả lưu trữ, bởi vì số mũ của một số float được gắn vào mỗi float, chỉ định ngầm định dấu thập phân ở đâu, nó là dự phòng ồ ạt, và do đó không hiệu quả cho công việc DB. Trong DB bạn đã biết điểm thập phân sẽ đi lên phía trước ở đâu và mỗi hàng trong bảng có giá trị cho cột DECIMAL chỉ cần nhìn vào thông số 1 & chỉ nơi đặt dấu thập phân đó trong lược đồ như là các đối số cho một DECIMAL (M, D) là hàm ý của các giá trị M và D.

Nhiều nhận xét được tìm thấy ở đây về định dạng nào sẽ được sử dụng cho các loại ứng dụng khác nhau là chính xác, vì vậy tôi sẽ không tin vào điều đó. Tôi đã dành thời gian để viết nó ở đây bởi vì bất cứ ai đang duy trì tài liệu trực tuyến MySQL được liên kết đều không hiểu bất kỳ điều nào ở trên và sau những nỗ lực ngày càng bực bội để giải thích cho họ, tôi đã từ bỏ. Một dấu hiệu tốt cho thấy họ hiểu những gì họ viết kém đến mức nào là cách trình bày rất lầy lội và gần như không thể giải mã được về vấn đề này.

Như một suy nghĩ cuối cùng, nếu bạn cần tính toán dấu phẩy động có độ chính xác cao, đã có những tiến bộ to lớn về mã dấu phẩy động trong 20 năm qua và hỗ trợ phần cứng cho phao chính xác 96 bit và Quadruple ở ngay góc, nhưng có những thư viện chính xác tùy ý tốt ngoài kia nếu thao tác của giá trị được lưu trữ là quan trọng.


Tôi tin rằng theo kiến ​​trúc Hazwell của Intel, có các hoạt động AVX-2 trên các số nguyên 256 bit, bao gồm mọi giá trị có thể có 77 chữ số, có thể được sử dụng để hoạt động trực tiếp trên các số nguyên chính xác mở rộng của DECIMAL. Việc Oracle có thể hỗ trợ một hình thức DECIMAL mới trong tương lai bao gồm 77 chữ số so với 65. Tôi sẽ ước tính cải thiện hiệu suất 5-10X bằng phần cứng thay vì phần mềm. 2 ^ 256 = 115.792.089.237.316.195.423.570.985.008.687.907.853.269.984.665.640.564.039.457.584.007.913.129, 639.936 (78 chữ số)

Bộ xử lý vector của Intel hiện hỗ trợ các hoạt động toán học 512 bit. Điều này sẽ bao gồm 154 chữ số. 2 ^ 512 = 13.407.807.929.942.597.099.574.024.998.205.846.127.479.365.820.592.393.377.723.561.443.721.764.030.073.546.976.801.874.298.166.903.427.690.031.858.186.486.050.853.753.882.811.946.569.946.433.649.006.084.096 (155 chữ số)

13

Không chỉ cụ thể đối với MySQL, sự khác biệt giữa các kiểu float và thập phân là cách chúng thể hiện các giá trị phân số. Các kiểu dấu phẩy động biểu thị các phân số trong nhị phân, chỉ có thể biểu thị các giá trị dưới dạng {m*2^n | m, n Integers}. các giá trị như 1/5 không thể được biểu diễn chính xác (không có lỗi làm tròn). Số thập phân được giới hạn tương tự, nhưng đại diện cho số như {m*10^n | m, n Integers}. Số thập phân vẫn không thể biểu thị các số như 1/3, nhưng thường là trong nhiều lĩnh vực phổ biến, như tài chính, kỳ vọng là các phân số thập phân nhất định luôn có thể được thể hiện mà không mất độ trung thực. Vì một số thập phân có thể đại diện cho một giá trị như $0.20(một phần năm của một đô la), nên nó được ưu tiên trong các tình huống đó.


Do bộ xử lý Intel thực hiện tất cả các hoạt động float kép trung gian với độ chính xác 80 bit, nên hầu như không có ngoại lệ không có lỗi làm tròn khi kết quả cuối cùng được cắt lại từ 80 bit thành 64 bit. Thậm chí nhiều thư viện phần mềm dấu phẩy động có thể xử lý những điều này và hàng trăm dị thường số học khác. Lý thuyết và thực hành vì thế rất khác nhau trong lĩnh vực này.

9

số thập phân dành cho số lượng cố định như tiền mà bạn muốn có một số vị trí thập phân cụ thể. Phao là để lưu trữ ... số chính xác điểm nổi.



5
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)

2

Nếu bạn theo đuổi hiệu suất và không chính xác, bạn nên lưu ý rằng các phép tính với số float nhanh hơn nhiều so với số thập phân


2

Các loại dấu phẩy động (Giá trị gần đúng) - FLOAT, NHÂN ĐÔI

Các loại FLOAT và NHÂN ĐÔI đại diện cho các giá trị dữ liệu số gần đúng . MySQL sử dụng bốn byte cho các giá trị độ chính xác đơn và tám byte cho các giá trị độ chính xác kép.

Đối với FLOAT, tiêu chuẩn SQL cho phép một đặc tả tùy chọn về độ chính xác (nhưng không phải là phạm vi của số mũ) theo các bit theo từ khóa FLOAT trong ngoặc đơn. MySQL cũng hỗ trợ đặc tả độ chính xác tùy chọn này, nhưng giá trị chính xác chỉ được sử dụng để xác định kích thước lưu trữ. Độ chính xác từ 0 đến 23 dẫn đến cột FLOAT có độ chính xác đơn 4 byte. Độ chính xác từ 24 đến 53 dẫn đến cột NHÂN ĐÔI độ chính xác kép 8 byte.

MySQL cho phép một cú pháp không chuẩn: FLOAT (M, D) hoặc REAL (M, D) hoặc PRECISION NHÂN ĐÔI (M, D). Ở đây, ngôn ngữ (M, D) có nghĩa là hơn các giá trị có thể được lưu trữ với tổng số chữ số M, trong đó chữ số D có thể nằm sau dấu thập phân. Ví dụ: một cột được xác định là FLOAT (7,4) sẽ trông giống như -999.9999 khi được hiển thị. MySQL thực hiện làm tròn khi lưu trữ giá trị, vì vậy nếu bạn chèn 999.00009 vào cột FLOAT (7.4), kết quả gần đúng là 999.0001.

Vì các giá trị dấu phẩy động là gần đúng và không được lưu trữ dưới dạng giá trị chính xác, nên các nỗ lực coi chúng là chính xác trong các so sánh có thể dẫn đến các vấn đề. Họ cũng phải phụ thuộc vào nền tảng hoặc phụ thuộc thực hiện.

Để có tính di động tối đa, mã yêu cầu lưu trữ các giá trị dữ liệu số gần đúng nên sử dụng FLOAT hoặc DOUBLE PRECISION mà không có thông số kỹ thuật về độ chính xác hoặc số chữ số.

https://dev.mysql.com/doc/refman/5.5/en/floating-point-types.html

Các vấn đề với giá trị dấu phẩy động

Số dấu phẩy động đôi khi gây nhầm lẫn vì chúng gần đúng và không được lưu dưới dạng giá trị chính xác . Giá trị dấu phẩy động như được viết trong câu lệnh SQL có thể không giống với giá trị được biểu thị bên trong. Nỗ lực coi các giá trị dấu phẩy động là chính xác trong các so sánh có thể dẫn đến các vấn đề. Họ cũng phải phụ thuộc vào nền tảng hoặc phụ thuộc thực hiện. Các kiểu dữ liệu FLOAT và NHÂN ĐÔI phải chịu các vấn đề này. Đối với các cột DECIMAL, MySQL thực hiện các hoạt động với độ chính xác 65 chữ số thập phân, điều này sẽ giải quyết hầu hết các vấn đề không chính xác phổ biến.

Ví dụ sau sử dụng NHÂN ĐÔI để trình bày cách tính toán được thực hiện bằng các phép toán dấu phẩy động có thể bị lỗi dấu phẩy động.

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 |
+------+-------+------+

Kết quả là chính xác. Mặc dù năm bản ghi đầu tiên trông giống như chúng không thỏa mãn so sánh (giá trị của a và b dường như không khác nhau), chúng có thể làm như vậy bởi vì sự khác biệt giữa các số hiển thị quanh thập phân thứ mười hoặc hơn, tùy thuộc vào các yếu tố chẳng hạn như kiến ​​trúc máy tính hoặc phiên bản trình biên dịch hoặc mức tối ưu hóa. Ví dụ, các CPU khác nhau có thể đánh giá các số dấu phẩy động khác nhau.

Nếu các cột d1 và d2 đã được xác định là KHAI THÁC chứ không phải NHÂN ĐÔI, thì kết quả của truy vấn CHỌN sẽ chỉ chứa một hàng Hồi giáo một hàng cuối cùng được hiển thị ở trên.

Cách chính xác để thực hiện so sánh số dấu phẩy động là trước tiên quyết định mức dung sai chấp nhận được đối với sự khác biệt giữa các số và sau đó thực hiện so sánh với giá trị dung sai. Ví dụ: nếu chúng tôi đồng ý rằng các số có dấu phẩy động nên được coi là giống nhau nếu chúng giống nhau trong độ chính xác một phần mười (0,0001), thì nên so sánh để tìm sự khác biệt lớn hơn giá trị dung sai:

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)

Ngược lại, để có được các hàng trong đó các số giống nhau, thử nghiệm phải tìm sự khác biệt trong giá trị dung sai:

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)

Các giá trị dấu phẩy động tùy thuộc vào nền tảng hoặc phụ thuộc triển khai. Giả sử bạn thực hiện các câu lệnh sau:

CREATE TABLE t1(c1 FLOAT(53,0), c2 FLOAT(53,0));
INSERT INTO t1 VALUES('1e+52','-1e+52');
SELECT * FROM t1;

Trên một số nền tảng, câu lệnh SELECT trả về inf và -inf. Trên những cái khác, nó trả về 0 và -0.

Một hàm ý của các vấn đề trước đó là nếu bạn cố gắng tạo một nô lệ sao chép bằng cách đổ nội dung bảng với mysqldump trên bản gốc và tải lại tệp kết xuất vào nô lệ, các bảng chứa các cột dấu phẩy động có thể khác nhau giữa hai máy chủ.

https://dev.mysql.com/doc/refman/5.5/en/probols-with-float.html


0

Quy tắc cứng & nhanh

Nếu tất cả những gì bạn cần làm là cộng, trừ hoặc nhân các số bạn đang lưu trữ, thì DECIMAL là tốt nhất.

Nếu bạn cần phân chia hoặc thực hiện bất kỳ hình thức số học hoặc đại số nào khác trên dữ liệu, bạn gần như chắc chắn sẽ hạnh phúc hơn với float. Các thư viện dấu phẩy động và trên bộ xử lý Intel, chính bộ xử lý dấu phẩy động, có TON các thao tác để sửa, sửa, phát hiện và xử lý các trường hợp ngoại lệ xảy ra khi thực hiện các hàm toán học điển hình - đặc biệt là các hàm siêu việt.

Về tính chính xác, tôi đã từng viết một hệ thống ngân sách tính toán phần trăm đóng góp của mỗi hơn 3.000 tài khoản, cho 3.600 đơn vị ngân sách, theo tháng cho nút hợp nhất của đơn vị đó, sau đó dựa trên ma trận tỷ lệ phần trăm (3.000 + x 12 x 3.600) Tôi đã nhân số tiền được ngân sách bởi các nút tổ chức cao nhất xuống 3 cấp tiếp theo của các nút tổ chức và sau đó tính toán tất cả (3.000 + 12) cho tất cả 3.200 đơn vị chi tiết từ đó. Hàng triệu và hàng triệu triệu triệu phép tính dấu phẩy động chính xác kép, bất kỳ một trong số đó sẽ loại bỏ tất cả các dự đoán đó trong một hợp nhất từ ​​dưới lên trở lại mức cao nhất trong tổ chức.

Tổng sai số dấu phẩy động sau tất cả các phép tính đó là ZERO . Đó là vào năm 1986, và các thư viện dấu phẩy động ngày nay tốt hơn nhiều so với trước đây. Intel thực hiện tất cả các tính toán trung gian tăng gấp đôi độ chính xác 80 bit, nhưng tất cả đều loại trừ lỗi làm tròn. Khi ai đó nói với bạn "đó là lỗi dấu phẩy động", điều đó gần như chắc chắn KHÔNG đúng.


-2

float(và double) đại diện cho phân số nhị phân

decimal đại diện cho phân số thập phân


-2
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

trong float khi đặt giá trị thành số nguyên in 10 nhưng ở số thập phân 11

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.