Câu hỏi Sự khác nhau giữa thập phân, phao và kép trong .NET?


Sự khác biệt giữa decimal, float và double trong lưới?

Khi ai đó sử dụng một trong số này?


1776
2018-03-06 11:31


gốc


bài báo thú vị zetcode.com/lang/csharp/datatypes - GibboK
@ Bargitta không đúng, có IS float trong lưới. Chỉ là System loại (tức là, không phải từ khóa) được gọi là Single. - Balázs
Liên quan: sandbox.mc.edu/~bennet/cs110/flt/dtof.html - Pacerier


Các câu trả lời:


float và double là nổi nhị phân loại điểm. Nói cách khác, chúng đại diện cho một số như sau:

10001.10010110011

Số nhị phân và vị trí của điểm nhị phân đều được mã hóa trong giá trị.

decimal là một nổi số thập phân loại điểm. Nói cách khác, chúng đại diện cho một số như sau:

12345.65789

Một lần nữa, số lượng và vị trí của số thập phân điểm đều được mã hóa trong giá trị - đó là điều làm cho decimal vẫn là loại dấu phẩy động thay vì loại điểm cố định.

Điều quan trọng cần lưu ý là con người được sử dụng để biểu diễn các số nguyên không theo dạng thập phân và mong đợi kết quả chính xác trong các biểu diễn thập phân; không phải tất cả các số thập phân được thể hiện chính xác trong điểm động nhị phân - 0,1, ví dụ - vì vậy nếu bạn sử dụng giá trị dấu phẩy động nhị phân, bạn sẽ thực sự nhận được xấp xỉ là 0,1. Bạn vẫn sẽ nhận được xấp xỉ khi sử dụng dấu thập phân dấu phẩy động - ví dụ: kết quả của việc chia 1 cho 3 không thể được biểu diễn chính xác.

Đối với những gì cần sử dụng khi:

  • Đối với các giá trị là "số thập phân chính xác tự nhiên", bạn nên sử dụng decimal. Điều này thường phù hợp với bất kỳ khái niệm nào được phát minh bởi con người: các giá trị tài chính là ví dụ rõ ràng nhất, nhưng cũng có những ví dụ khác. Hãy xem xét điểm số cho các thợ lặn hoặc trượt băng, ví dụ.

  • Đối với các giá trị có nhiều đồ tạo tác của thiên nhiên không thể đo được chính xác dù sao, float/double phù hợp hơn. Ví dụ, dữ liệu khoa học thường được thể hiện dưới dạng này. Ở đây, các giá trị ban đầu sẽ không "bắt đầu chính xác" để bắt đầu, vì vậy không quan trọng đối với kết quả mong đợi để duy trì "độ chính xác thập phân". Các kiểu điểm nhị phân nổi nhanh hơn nhiều so với số thập phân.


1969
2018-03-06 11:56



float/double thường không đại diện cho số 101.101110, thông thường nó được thể hiện như một cái gì đó như 1101010 * 2^(01010010) - số mũ - Mingwei Samuel
@ Hazzard: Đó là những gì "và vị trí của điểm nhị phân" một phần của câu trả lời có nghĩa là. - Jon Skeet
Tôi ngạc nhiên khi nó chưa được nói, float là từ khóa bí danh C # và không phải là loại .Net. nó là System.Single.. single và double là các loại điểm nhị phân thả nổi. - Brett Caswell
chờ đợi .... không phải là một số thập phân đại diện trong 1s và 0s cuối cùng? Tôi nghĩ rằng máy tính chỉ có thể hoạt động ở dạng nhị phân. vì vậy sau đó một thập phân cuối cùng là một loại nhị phân phải không? - BKSpurgeon
@BKSpurgeon: Vâng, chỉ trong cùng một cách mà bạn có thể nói rằng mọi điều là một kiểu nhị phân, lúc này nó trở thành một định nghĩa khá vô dụng. Thập phân là một kiểu thập phân ở chỗ nó là một số được biểu diễn dưới dạng một số nguyên và một tỷ lệ, sao cho kết quả là scaleand * 10 ^, trong khi float và double là scaleand * 2 ^ scale. Bạn lấy một số được viết theo số thập phân, và di chuyển dấu thập phân đến đủ về phía bên phải mà bạn đã có số nguyên để tính toán mức độ và tỷ lệ. Đối với float / double, bạn bắt đầu với một số được viết bằng nhị phân. - Jon Skeet


Độ chính xác là sự khác biệt chính.

Phao - 7 chữ số (32 bit)

Gấp đôi-15-16 chữ số (64 bit)

Thập phân -28-29 chữ số có nghĩa (128 bit)

Số thập phân có độ chính xác cao hơn nhiều và thường được sử dụng trong các ứng dụng tài chính yêu cầu độ chính xác cao. Số thập phân là chậm hơn nhiều (lên đến 20 lần trong một số thử nghiệm) so với một đôi / phao.

Decimals và Floats / Doubles không thể so sánh nếu không có cast trong khi Floats và Double có thể. Số thập phân cũng cho phép mã hóa hoặc số không theo sau.

float flt = 1F/3;
double dbl = 1D/3;
decimal dcm = 1M/3;
Console.WriteLine("float: {0} double: {1} decimal: {2}", flt, dbl, dcm);

Kết quả :

float: 0.3333333  
double: 0.333333333333333  
decimal: 0.3333333333333333333333333333

896
2018-03-06 11:33



@Thecrocodilehunter: xin lỗi, nhưng không. Thập phân có thể biểu thị tất cả các số có thể được biểu diễn bằng ký hiệu thập phân, nhưng không thể biểu thị bằng 1/3 chẳng hạn. 1.0m / 3.0m sẽ đánh giá thành 0.33333333 ... với số lượng lớn nhưng hữu hạn 3 giây ở cuối. Nhân nó bằng 3 sẽ không trả lại chính xác 1.0. - Erik P.
@Thecrocodilehunter: Tôi nghĩ rằng bạn đang bối rối chính xác và chính xác. Chúng là những thứ khác nhau trong bối cảnh này. Độ chính xác là số chữ số có sẵn để biểu thị một số. Độ chính xác hơn, bạn càng cần phải làm tròn. Không có loại dữ liệu nào có độ chính xác vô hạn. - Igby Largeman
@Thecrocodilehunter: Bạn giả định rằng giá trị được đo là chính xác  0.1 - đó là hiếm khi trường hợp trong thế giới thực! Bất kì định dạng lưu trữ hữu hạn sẽ conflate một số lượng vô hạn của các giá trị có thể cho một số hữu hạn của các mẫu bit. Ví dụ, float sẽ conflate 0.1 và 0.1 + 1e-8, trong khi decimal sẽ conflate 0.1 và 0.1 + 1e-29. Chắc chắn rồi, trong phạm vi nhất định, một số giá trị nhất định có thể được biểu diễn ở bất kỳ định dạng nào mà không bị mất độ chính xác (ví dụ: float có thể lưu trữ bất kỳ số nguyên nào lên tới 1.6e7 mà không bị mất độ chính xác) - nhưng vẫn không vô hạn chính xác. - Daniel Pryden
@Thecrocodilehunter: Bạn đã bỏ lỡ quan điểm của tôi. 0.1 Là không phải là một giá trị đặc biệt! Điều duy nhất khiến 0.1 "tốt hơn 0.10000001 là vì loài người như cơ sở 10. Và thậm chí với một float giá trị, nếu bạn khởi tạo hai giá trị với 0.1 theo cùng một cách, cả hai đều có cùng giá trị. Chỉ là giá trị đó sẽ không chính xác  0.1 -- nó sẽ là giá trị gần nhất với 0.1có thể được biểu diễn chính xác như một float. Chắc chắn, với các phao nhị phân, (1.0 / 10) * 10 != 1.0, nhưng với phao thập phân, (1.0 / 3) * 3 != 1.0 hoặc. Cũng không Là hoàn toàn tóm lược. - Daniel Pryden
@Thecrocodilehunter: Bạn vẫn không hiểu. Tôi không biết làm thế nào để nói điều này rõ ràng hơn: Trong C, nếu bạn làm double a = 0.1; double b = 0.1; sau đó a == b  sẽ là sự thật. Chỉ là a và b sẽ cả hai không chính xác như nhau 0.1. Trong C #, nếu bạn làm decimal a = 1.0m / 3.0m; decimal b = 1.0m / 3.0m; sau đó a == b cũng sẽ đúng. Nhưng trong trường hợp đó, cũng không của a cũng không b sẽ chính xác công bằng 1/3 - cả hai sẽ bằng nhau 0.3333.... Trong cả hai trường hợp, một số độ chính xác bị mất do đại diện. Bạn ngoan cố nói rằng decimal có độ chính xác "vô hạn", là sai. - Daniel Pryden


Cấu trúc thập phân được thiết kế chặt chẽ để tính toán tài chính đòi hỏi độ chính xác, tương đối không dung nạp làm tròn. Tuy nhiên, số thập phân không đủ cho các ứng dụng khoa học vì một số lý do:

  • Sự mất chính xác nhất định có thể chấp nhận được trong nhiều phép tính khoa học vì các giới hạn thực tế của vấn đề vật lý hoặc vật được đo. Mất chính xác không được chấp nhận trong tài chính.
  • Decimal chậm hơn nhiều so với float và double cho hầu hết các hoạt động, chủ yếu vì các phép toán floating point được thực hiện trong binary, trong khi Decimal stuff được thực hiện ở base 10 (tức là float và double được xử lý bởi phần cứng FPU, chẳng hạn như MMX / SSE , trong khi số thập phân được tính bằng phần mềm).
  • Thập phân có một phạm vi giá trị nhỏ hơn không thể chấp nhận được gấp đôi, mặc dù thực tế là nó hỗ trợ nhiều chữ số chính xác hơn. Do đó, không thể sử dụng thập phân để biểu thị nhiều giá trị khoa học.

66
2018-04-13 13:55



Nếu bạn đang tính toán tài chính, bạn hoàn toàn phải cuộn các kiểu dữ liệu của riêng bạn hoặc tìm một thư viện phù hợp với nhu cầu chính xác của bạn. Độ chính xác trong một môi trường tài chính được xác định bởi các cơ quan tiêu chuẩn (con người) và chúng có các quy tắc địa phương hóa cụ thể (cả về thời gian và địa lý) về cách tính toán. Những thứ như làm tròn chính xác không bị bắt trong các kiểu dữ liệu số đơn giản trong .Net. Khả năng tính toán chỉ là một phần rất nhỏ của câu đố. - James Moore


enter image description here

để biết thêm thông tin, bạn có thể vào nguồn của bức ảnh này:

http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/921a8ffc-9829-4145-bdc9-a96c1ec174a5


54
2018-06-07 12:50



-1 cho tuyên bố rằng thập phân là 96 bit. MSDN nói rõ ràng 128. - Ben Voigt
Và nếu bạn đào sâu hơn, nó được sử dụng 102 bit, 128 được lưu trữ. Không có cách nào để phù hợp trong 12 byte. - Ben Voigt
Bạn đã bỏ qua sự khác biệt lớn nhất, là cơ sở được sử dụng cho loại thập phân (thập phân được lưu trữ dưới dạng cơ sở 10, tất cả các loại số khác được liệt kê là cơ số 2). - BrainSlugs83
Phạm vi giá trị cho Đơn và Đôi không được mô tả chính xác trong hình ảnh ở trên hoặc bài đăng trên diễn đàn nguồn. Vì chúng tôi không thể dễ dàng thay thế văn bản ở đây, hãy sử dụng ký tự dấu mũ: Đơn phải là 10 ^ -45 và 10 ^ 38 và Double phải là 10 ^ -324 và 10 ^ 308. Ngoài ra, MSDN có phao với phạm vi -3.4x10 ^ 38 đến + 3.4x10 ^ 38. Tìm kiếm MSDN cho System.Single và System.Double trong trường hợp thay đổi liên kết. Độc thân: msdn.microsoft.com/en-us/library/b1e65aza.aspx Gấp đôi: msdn.microsoft.com/en-us/library/678hzkk9.aspx - deegee


float 7 chữ số chính xác

double có khoảng 15 chữ số chính xác

decimal có khoảng 28 chữ số chính xác

Nếu bạn cần độ chính xác tốt hơn, hãy sử dụng double thay vì float. Trong các CPU hiện đại, cả hai loại dữ liệu đều có hiệu suất giống nhau. Lợi ích duy nhất của việc sử dụng phao là chúng chiếm ít không gian hơn. Thực tế chỉ có vấn đề nếu bạn có nhiều người trong số họ.

Tôi thấy điều này thật thú vị. Mỗi nhà khoa học máy tính nên biết gì về số học dấu chấm động


40
2017-08-29 00:06



@RogerLipscombe: Tôi sẽ cân nhắc double thích hợp trong các ứng dụng kế toán trong những trường hợp đó (và về cơ bản chỉ những trường hợp đó) mà không có loại số nguyên nào lớn hơn 32 bit, và double đã được sử dụng như thể nó là một loại số nguyên 53 bit (ví dụ: để giữ toàn bộ số xu, hoặc toàn bộ số phần trăm của một xu). Không sử dụng nhiều cho những thứ như vậy ngày nay, nhưng nhiều ngôn ngữ đã đạt được khả năng sử dụng các giá trị dấu phẩy động kép chính xác lâu trước khi chúng đạt được 64 bit (hoặc trong một số trường hợp thậm chí 32 bit!). - supercat
Câu trả lời của bạn ngụ ý độ chính xác là sự khác biệt duy nhất giữa các loại dữ liệu này. Cho số học dấu chấm động nhị phân thường được thực hiện trong phần cứng FPU, hiệu suất là một sự khác biệt đáng kể. Điều này có thể không quan trọng đối với một số ứng dụng, nhưng rất quan trọng đối với những ứng dụng khác. - saille
@supercat double là không bao giờ thích hợp trong các ứng dụng kế toán. Bởi vì Double chỉ có thể xấp xỉ giá trị thập phân (ngay cả trong phạm vi độ chính xác riêng của nó). Điều này là do hai lưu trữ các giá trị theo định dạng cơ bản-nhị phân (nhị phân). - BrainSlugs83
@ BrainSlugs83: Sử dụng các loại dấu phẩy động để giữ không toàn bộ số số lượng sẽ không đúng, nhưng trong lịch sử rất phổ biến đối với các ngôn ngữ có các loại dấu phẩy động có thể đại diện chính xác các giá trị số nguyên lớn hơn các loại số nguyên của chúng có thể đại diện. Có lẽ ví dụ cực đoan nhất là Turbo-87 chỉ có các loại số nguyên được giới hạn trong -32768 đến +32767, nhưng Real IIRC có thể biểu thị các giá trị lên đến 1.8E + 19 với độ chính xác của đơn vị không. Tôi nghĩ rằng nó sẽ an toàn hơn cho một ứng dụng kế toán để sử dụng Real để đại diện cho toàn bộ số tiền hơn ... - supercat
... cho nó để cố gắng thực hiện toán học đa độ chính xác bằng cách sử dụng một loạt các giá trị 16 bit. Đối với hầu hết các ngôn ngữ khác sự khác biệt không phải là cực đoan, nhưng trong một thời gian dài nó đã được rất phổ biến cho các ngôn ngữ không có bất kỳ loại nguyên mà vượt quá 4E9 nhưng có một double loại có độ chính xác đến 9E15. Nếu cần lưu trữ số nguyên lớn hơn số nguyên có sẵn lớn nhất, sử dụng double là apt đơn giản và hiệu quả hơn so với cố gắng để fudge toán học đa chính xác, đặc biệt là cho rằng trong khi bộ vi xử lý có hướng dẫn để thực hiện 16x16-> 32 hoặc ... - supercat


Không ai nói rằng

Trong các thiết lập mặc định, Floats (System.Single) và double (System.Double) sẽ không bao giờ sử dụng   kiểm tra tràn trong khi thập phân (System.Decimal) sẽ luôn sử dụng   kiểm tra tràn.

Ý tôi là

decimal myNumber = decimal.MaxValue;
myNumber += 1;

ném OverflowException.

Nhưng những điều này không:

float myNumber = float.MaxValue;
myNumber += 1;

&

double myNumber = double.MaxValue;
myNumber += 1;

29
2018-01-02 13:12



float.MaxValue+1 == float.MaxValue, giống như decimal.MaxValue+0.1D == decimal.MaxValue. Có lẽ bạn có ý nghĩa như float.MaxValue*2? - supercat
@supercar Nhưng không đúng là số thập phân.MaxValue + 1 == decimal.MaxValue - GorkemHalulu
@supercar decimal.MaxValue + 0.1m == decimal.MaxValue ok - GorkemHalulu
Các System.Decimal ném một ngoại lệ ngay trước khi nó trở thành không thể phân biệt toàn bộ các đơn vị, nhưng nếu một ứng dụng được cho là phải xử lý với ví dụ. đô la và xu, có thể là quá muộn. - supercat


  1. Double và float có thể chia cho số nguyên không có ngoại lệ ở cả thời gian biên dịch và thời gian chạy.
  2. Số thập phân không thể chia cho số nguyên không. Biên dịch sẽ luôn thất bại nếu bạn làm điều đó.

25
2017-07-29 07:21



Họ chắc chắn có thể! Chúng cũng có một vài giá trị "ma thuật" như Infinity, Negative Infinity, và NaN (không phải là số), điều này rất hữu ích cho việc phát hiện các đường thẳng đứng trong khi tính toán dốc ... Hơn nữa, nếu bạn cần quyết định giữa việc gọi phao .TryParse, double.TryParse và decimal.TryParse (để phát hiện nếu chuỗi là số, ví dụ), tôi khuyên bạn nên sử dụng gấp đôi hoặc nổi, vì chúng sẽ phân tích cú pháp "Vô cực", "-Infinity" và "NaN" đúng cách , trong khi số thập phân thì không. - BrainSlugs83
Biên soạn chỉ thất bại nếu bạn cố gắng chia một chữ decimal bằng không (CS0020), và điều tương tự cũng đúng với các chữ số nguyên. Tuy nhiên, nếu một giá trị thập phân thời gian chạy được chia cho số không, bạn sẽ nhận được một ngoại lệ không phải là một lỗi biên dịch. - Drew Noakes
@ BrainSlugs83 Tuy nhiên, bạn có thể không muốn phân tích "Infinity" hoặc "NaN" tùy thuộc vào ngữ cảnh. Có vẻ như một khai thác tốt cho người dùng đầu vào nếu developper không đủ cứng nhắc. - Winter


Tôi sẽ không nhắc lại hàng tấn thông tin tốt (và một số thông tin xấu) đã được trả lời trong các câu trả lời và nhận xét khác, nhưng tôi sẽ trả lời câu hỏi tiếp theo của bạn bằng một mẹo:

Khi ai đó sử dụng một trong số này?

Sử dụng số thập phân cho được tính giá trị

Sử dụng float / double cho đo lường giá trị

Vài ví dụ:

  • tiền (chúng ta có tính tiền hay đo tiền không?)

  • khoảng cách (chúng ta có tính khoảng cách hay khoảng cách đo? *)

  • điểm số (chúng tôi có tính điểm hoặc đo điểm số không?)

Chúng tôi luôn tính tiền và không bao giờ nên đo lường nó. Chúng tôi thường đo khoảng cách. Chúng tôi thường đếm điểm số.

* Trong một số trường hợp, những gì tôi sẽ gọi khoảng cách danh nghĩa, chúng tôi thực sự có thể muốn 'đếm' khoảng cách. Ví dụ: có thể chúng ta đang xử lý các dấu hiệu quốc gia cho thấy khoảng cách đến các thành phố và chúng tôi biết rằng những khoảng cách đó không bao giờ có nhiều hơn một chữ số thập phân (xxx.x km).


25
2018-04-22 15:18





Các kiểu biến Decimal, Double và Float khác nhau theo cách chúng lưu trữ các giá trị. Độ chính xác là sự khác biệt chính trong đó float là kiểu dữ liệu điểm nổi chính xác (32 bit), double là kiểu dữ liệu dấu chấm động (64 bit) và số thập phân là kiểu dữ liệu dấu phẩy động 128 bit.

Float - 32 bit (7 chữ số)

Đôi - 64 bit (15-16 chữ số)

Thập phân - 128 bit (28-29 chữ số có nghĩa)

Sự khác biệt chính là Floats và Doubles là các kiểu dấu phẩy động nhị phân và một số thập phân sẽ lưu trữ giá trị dưới dạng một dấu chấm thập phân. Vì vậy, số thập phân có độ chính xác cao hơn nhiều và thường được sử dụng trong các ứng dụng tính toán tiền tệ (tài chính) hoặc khoa học đòi hỏi độ chính xác cao. Nhưng trong hiệu suất khôn ngoan Decimals là chậm hơn so với đôi và các loại phao.

Thập phân có thể chính xác 100% đại diện cho bất kỳ số nào trong độ chính xác của định dạng thập phân, trong khi Float và Đôi, không thể đại diện chính xác cho tất cả các số, thậm chí các số nằm trong độ chính xác định dạng tương ứng.

Thập phân

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

Gấp đôi

Loại đôi 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.

Phao

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


24
2018-06-19 04:34



Wow thập phân là 128 bit? TIL - Gaspa79


Số nguyên, như đã được đề cập, là số nguyên. Họ không thể lưu trữ điểm một cái gì đó, như .7, .42, và .007. Nếu bạn cần lưu trữ các số không phải là số nguyên, bạn cần một loại biến khác. Bạn có thể sử dụng kiểu kép hoặc kiểu float. Bạn đặt các loại biến này theo cùng một cách: thay vì sử dụng từ int, bạn gõ double hoặc là float. Như thế này:

float myFloat;
double myDouble;

(float là viết tắt của "dấu chấm động", và chỉ có nghĩa là một số có điểm gì đó ở cuối.)

Sự khác biệt giữa hai là kích thước của các con số mà họ có thể nắm giữ. Dành cho float, bạn có thể có tối đa 7 chữ số trong số của mình. Dành cho doubles, bạn có thể có tối đa 16 chữ số. Để chính xác hơn, đây là kích thước chính thức:

float:  1.5 × 10^-45  to 3.4 × 10^38  
double: 5.0 × 10^-324 to 1.7 × 10^308

float là số 32 bit và double là số 64 bit.

Nhấp đúp vào nút mới của bạn để nhận mã. Thêm ba dòng sau vào mã nút của bạn:

double myDouble;
myDouble = 0.007;
MessageBox.Show(myDouble.ToString());

Dừng chương trình của bạn và quay lại cửa sổ mã hóa. Thay đổi dòng này:

myDouble = 0.007;
myDouble = 12345678.1234567;

Chạy chương trình của bạn và nhấp vào nút kép của bạn. Hộp tin nhắn hiển thị chính xác số. Thêm một số khác vào cuối, mặc dù, và C # một lần nữa sẽ làm tròn lên hoặc xuống. Đạo đức là nếu bạn muốn chính xác, hãy cẩn thận làm tròn!


23
2018-05-22 12:05



Được thăng hạng để sử dụng .42 và .007 trong ví dụ của bạn. : D - PruitIgoe
"Cái gì đó" bạn đã đề cập thường được gọi là "phần phân số" của một số. "Điểm nổi" không có nghĩa là "một số có điểm gì đó ở cuối"; nhưng thay vào đó "Điểm nổi" phân biệt loại số, thay vì số "Điểm cố định" (cũng có thể lưu trữ giá trị phân số); sự khác biệt là liệu độ chính xác có được cố định hay không. - Số dấu chấm động cung cấp cho bạn phạm vi giá trị động lớn hơn nhiều (Min và Max), với chi phí chính xác, trong khi số điểm cố định cung cấp cho bạn số lượng chính xác không đổi theo chi phí phạm vi. - BrainSlugs83


Đây là một chủ đề thú vị đối với tôi, như hôm nay, chúng tôi đã có một lỗi nhỏ khó chịu, liên quan đến decimal có độ chính xác kém hơn float.

Trong mã C # của chúng tôi, chúng tôi đang đọc các giá trị số từ một bảng tính Excel, chuyển đổi chúng thành một decimal, sau đó gửi decimal quay lại Dịch vụ để lưu vào Máy chủ SQL cơ sở dữ liệu.

Microsoft.Office.Interop.Excel.Range cell = …
object cellValue = cell.Value2;
if (cellValue != null)
{
    decimal value = 0;
    Decimal.TryParse(cellValue.ToString(), out value);
}

Bây giờ, cho gần như tất cả các giá trị Excel của chúng tôi, điều này làm việc rất đẹp. Nhưng đối với một số giá trị Excel rất nhỏ, sử dụng decimal.TryParse mất giá trị hoàn toàn. Một ví dụ như vậy là

  • cellValue = 0,00006317592

  • Decimal.TryParse (cellValue.ToString (), giá trị ngoài); // sẽ trở lại 0

Giải pháp, kỳ lạ, là chuyển đổi các giá trị Excel thành một double đầu tiên, và sau đó vào decimal:

Microsoft.Office.Interop.Excel.Range cell = …
object cellValue = cell.Value2;
if (cellValue != null)
{
    double valueDouble = 0;
    double.TryParse(cellValue.ToString(), out valueDouble);
    decimal value = (decimal) valueDouble;
    …
}

Mặc du double có độ chính xác thấp hơn decimal, điều này thực sự đảm bảo số lượng nhỏ sẽ vẫn được công nhận. Đối với một số lý do, double.TryParse thực sự có thể truy xuất các số nhỏ như vậy, trong khi decimal.TryParse sẽ đặt chúng về 0.

Odd. Rất kỳ quặc.


13
2018-04-16 09:23



Trong tò mò, giá trị thô của cellValue.ToString () là gì? Decimal.TryParse ("0.00006317592", ra val) dường như hoạt động ... - micahtan
-1 Đừng làm cho tôi sai, nếu đúng, nó rất thú vị nhưng đây là một câu hỏi riêng biệt, nó chắc chắn không phải là câu trả lời cho câu hỏi này. - weston
Có lẽ vì ô Excel đã trả về giá trị double và ToString () là "6.31759E-05" do đó số thập phân.Parse () không thích ký pháp. Tôi đặt cược nếu bạn kiểm tra giá trị trả về của Decimal.TryParse () nó sẽ là sai. - SergioL
@weston Các câu trả lời thường bổ sung cho các câu trả lời khác bằng cách điền vào các sắc thái mà chúng đã bỏ qua. Câu trả lời này làm nổi bật sự khác biệt về phân tích cú pháp. Nó là rất nhiều câu trả lời cho câu hỏi này! - Robino
Er ... decimal.Parse("0.00006317592") công trình - bạn đã có một cái gì đó khác đang diễn ra. - Có thể ký hiệu khoa học? - BrainSlugs83