Khi nào nên sử dụng float so với thập phân


14

Tôi đang xây dựng API này và cơ sở dữ liệu sẽ lưu trữ các giá trị đại diện cho một trong những điều sau đây:

  • tỷ lệ phần trăm
  • Trung bình cộng
  • tỷ lệ

Tôi thực sự không có ý tưởng làm thế nào để đại diện cho một cái gì đó mà phạm vi nằm trong khoảng từ 0 đến 100% bằng số. Nó phải được

  • 0,00 - 1,00
  • 0,00 - 100,00
  • bất kỳ sự thay thế nào khác mà tôi không biết

Có một sự lựa chọn rõ ràng cho điều đó? Một cách đại diện toàn cầu trên cơ sở dữ liệu một cái gì đó đi từ 0 đến 100% phần trăm? Đi xa hơn, loại chính xác cho nó, float hay thập phân là gì?

Cảm ơn bạn.



5
Số có thể được lưu trữ theo nhiều cách. Không có gì sai khi lưu trữ tỷ lệ phần trăm bằng 0-100 hoặc sử dụng 0-1. Điều quan trọng là những gì bạn cần làm với những con số, độ chính xác bạn cần, v.v. Bạn phải giải thích thêm ngữ cảnh trước khi có thể đưa ra một câu trả lời hay. Bạn có cần lưu trữ các số có thể biểu diễn chính xác với một số lượng nhỏ các chữ số thập phân không? Nếu bạn trung bình, bạn nhận được phân số như phần ba hoặc phần bảy. Bạn có cần lưu trữ chính xác? Hay chỉ xấp xỉ? Làm thế nào khoảng? Bạn sẽ làm gì với họ?
Eric Postpischil

1
Nếu các giá trị là 0,00 đến 100,00 trong các bước 0,01 thì đó là 10001 giá trị khác nhau. Chỉ cần sử dụng một intđể đại diện cho hàng trăm hoặc theo đơn vị Permyriad hoặc.
chux - Phục hồi lại

@ chux-ReinstateMonica - Có, "số nguyên tỷ lệ" là có thể, nhưng vụng về.
Rick James

@RickJames Có lẽ. Tôi không tìm thấy số nguyên tỷ lệ khó khăn.
chux - Tái lập lại

Câu trả lời:


4

Tôi sẽ có lập trường ngược lại.

FLOATdành cho các số gần đúng, chẳng hạn như tỷ lệ phần trăm, trung bình, v.v. Bạn nên định dạng khi bạn hiển thị các giá trị, trong mã ứng dụng hoặc sử dụng FORMAT()chức năng của MySQL.

Đừng bao giờ thử nghiệm float_value = 1.3; có nhiều lý do tại sao điều đó sẽ thất bại.

DECIMALnên được sử dụng cho các giá trị tiền tệ. DECIMALtránh làm tròn số thứ hai khi giá trị cần được làm tròn thành đô la / xu / euro / v.v. Kế toán không thích phân số xu.

Việc triển khai của MySQL DECIMALcho phép 65 chữ số có nghĩa; FLOATđưa ra khoảng 7 và DOUBLEkhoảng 16. 7 thường là quá đủ cho các cảm biến và tính toán khoa học.

Còn về "phần trăm" - Đôi khi tôi đã sử dụng TINYINT UNSIGNEDkhi tôi chỉ muốn sử dụng 1 byte dung lượng lưu trữ và không cần nhiều độ chính xác; đôi khi tôi đã sử dụng FLOAT(4 byte). Không có kiểu dữ liệu được điều chỉnh cụ thể cho tỷ lệ phần trăm. (Cũng lưu ý rằng DECIMAL(2,0)không thể giữ giá trị 100, vì vậy về mặt kỹ thuật bạn sẽ cần DECIMAL(3,0).)

Hoặc đôi khi tôi đã sử dụng FLOATgiá trị giữ từ 0 đến 1. Nhưng sau đó tôi sẽ cần đảm bảo nhân với 100 trước khi hiển thị "phần trăm".

Hơn

Tất cả ba "tỷ lệ phần trăm, trung bình, tỷ lệ" giống như phao, vì vậy đó sẽ là lựa chọn đầu tiên của tôi.

Một tiêu chí để quyết định kiểu dữ liệu ... Sẽ tồn tại bao nhiêu bản sao của giá trị?

Nếu bạn có một bảng hàng tỷ với một cột cho tỷ lệ phần trăm, hãy xem xét rằng TINYINTsẽ mất 1 byte (tổng cộng 1 GB), nhưngFLOAT sẽ mất 4 byte (tổng cộng 4GB). OTOH, hầu hết các ứng dụng không có nhiều hàng, vì vậy điều này có thể không liên quan.

Theo quy tắc 'chung', các giá trị "chính xác" nên sử dụng một số dạng INThoặc DECIMAL. Những thứ không chính xác (tính toán khoa học, căn bậc hai, phép chia, v.v.) nên sử dụng FLOAT(hoặc DOUBLE).

Hơn nữa, định dạng của đầu ra thường nên được đặt ở mặt trước của ứng dụng. Đó là, mặc dù "mức trung bình" có thể tính thành "14.6666666 ...", màn hình sẽ hiển thị giống như "14.7"; điều này thân thiện hơn với con người Trong khi đó, bạn có giá trị cơ bản để sau đó quyết định rằng "15" hoặc "14.667" là định dạng đầu ra thích hợp hơn.

Phạm vi "0,00 - 100,00" có thể được thực hiện bằng FLOAT và sử dụng định dạng đầu ra hoặc với DECIMAL(5,2)(3 byte) với xác định trước mà bạn sẽ luôn muốn độ chính xác được chỉ định .


3

Tôi thường khuyên bạn không nên sử dụng float. Các số dấu phẩy động đại diện cho các số trong cơ sở 2, khiến cho một số số (chính xác) được làm tròn trong các hoạt động hoặc so sánh, bởi vì chúng không thể được lưu trữ chính xác trong cơ sở 2. Điều này có thể dẫn đến các hành vi bất ngờ.

Hãy xem xét ví dụ sau :

create table t (num float);
insert into t values(1.3);

select * from t;

| num |
| --: |
| 1.3 |

select * from t where num = 1.3;

| num |
| --: |

Cơ sở so sánh số 2 1.3không thành công. Đây là khó khăn.

Trong so sánh, thập phân cung cấp một đại diện chính xác của số hữu hạn trong phạm vi của chúng. Nếu bạn thay đổi floatđể decimal(2, 1)trong ví dụ trên, bạn làm được những kết quả mong đợi.


4
Câu trả lời này là sai trong một số liên quan. So sánh, thập phân có một phạm vi nhỏ hơn nhưng cung cấp một đại diện chính xác của các số hữu hạn trong phạm vi đó là sai: Số thập phân không đại diện cho chính xác. Một số con số (chính xác, hữu hạn) được làm tròn là không chính xác; những con số không phải là những người làm tròn. Chuyển đổi và các hoạt động khác có thể làm tròn. Chế độ làm tròn mặc định là phổ biến nhất từ ​​làm tròn đến gần nhất, thậm chí không làm tròn.
Eric Postpischil

4
Các vấn đề với độ chính xác không phải là do các số dấu phẩy động của Điên mà đơn giản là do các biểu diễn số: Tất cả các biểu diễn số hữu hạn có độ chính xác hạn chế: Dấu phẩy động, điểm cố định, số nguyên, số thập phân, số thập phân, nhị phân, mọi thứ.
Eric Postpischil

2
Thở dài. Bạn đã sửa cái gì? Nhận xét của tôi nói rằng câu trả lời là sai bởi vì nó nói thập phân cung cấp một đại diện chính xác của các số trong phạm vi của nó, nhưng thực tế thì không phải vì nó không cung cấp một đại diện chính xác cho. Sự thay đổi nói rằng chính xác và thay vì chính xác, nhưng tại sao không phải là dấu phẩy động nhị phân cũng không chính xác đối với ⅓ và cả hai hoặc không chính xác, tùy thuộc vào ngưỡng chính xác của bạn là bao nhiêu và độ chính xác là bao nhiêu họ có. Câu hỏi cho biết trung bình sẽ được trình bày và tính trung bình ba điều mang lại cho bạn các số như.
Eric Postpischil

4
Nhận xét nói rằng mối quan hệ từ tròn đến gần nhất được sử dụng phổ biến nhất, nhưng câu trả lời vẫn nói là làm tròn. Câu trả lời cho biết so sánh có thể làm tròn, nhưng so sánh là hoàn hảo: So sánh luôn trả về một kết quả chính xác về mặt toán học, không làm tròn số. (Một số ngôn ngữ lập trình có thể chuyển đổi toán hạng trước khi so sánh, nhưng đó là các hoạt động riêng biệt.)
Eric Postpischil

1
1/3 không thể được biểu diễn chính xác bằng nhị phân hoặc thập phân. Giảm giá 20% so với $ 14,99 sẽ yêu cầu làm tròn số xu không tồn tại.
Rick James

0

Sự khác biệt giữa float và thập phân là độ chính xác. Số thập phân có thể biểu thị chính xác 100% bất kỳ số nào trong độ chính xác của định dạng thập phân, trong khi Float, không thể biểu diễn chính xác tất cả các số.

Sử dụng Decimal cho ví dụ giá trị liên quan đến tài chính và sử dụng float cho ví dụ giá trị liên quan đến đồ họa


0

Tôi khuyên bạn nên sử dụng decimal(5,2)nếu bạn sẽ lưu trữ nó giống như cách bạn sẽ hiển thị nó vì decimalđể bảo vệ độ chính xác chính xác. (Xem https://dev.mysql.com/doc/refman/8.0/en/fixed-point-types.html )

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.

( https://dev.mysql.com/doc/refman/8.0/en/floating-point-types.html )

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.

Đố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.

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


0

Số thập phân: Trong trường hợp ứng dụng tài chính, tốt hơn là sử dụng loại Số thập phân vì nó mang lại cho bạn mức độ chính xác cao và dễ tránh các lỗi làm tròn

Double: Double Type có lẽ là loại dữ liệu được sử dụng phổ biến nhất cho các giá trị thực, ngoại trừ xử lý tiền.

Float: Nó được sử dụng chủ yếu trong các thư viện đồ họa bởi vì nhu cầu xử lý rất cao, cũng được sử dụng trong các tình huống có thể chịu đựng các lỗi làm tròn.

Tham khảo: http://net-informations.com/q/faq/float.html


0
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

*********************************************************************

@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, số thập phân là tốt hơn, nhưng đối với các phân chia, float là tốt hơn, đến một số điểm, tất nhiên. Ý tôi là, sử dụng DECIMAL sẽ không cung cấp cho bạn "số học không chứng minh" trong bất kỳ phương tiện nào.

Hy vọng điều này có thể giúp cho bạn.


0

Trong tsql: Float, 0,0 lưu dưới dạng 0 và không yêu cầu xác định sau chữ số thập phân, ví dụ: bạn không cần phải viết Float (4.2). Số thập phân, 0,0 lưu trữ là 0,0 và nó có tùy chọn để xác định như số thập phân (4.2), tôi sẽ đề xuất 0,00-1,00, bằng cách này, bạn có thể tính giá trị của phần trăm đó mà không nhân với 100 và nếu bạn báo cáo thì hãy đặt loại dữ liệu của cột đó là phần trăm như MS Excel và chế độ xem nền tảng khác như thế nào 0.5 -> 50%.

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.