floating-point 부동소수점 c# - .NET에서 decimal, float 및 double의 차이점은 무엇입니까?



8 Answers

정밀도가 가장 큰 차이점입니다.

Float - 7 자리 (32 비트)

Double -15-16 자리 (64 비트)

Decimal -28-29 유효 자릿수 (128 비트)

십진수는 훨씬 더 높은 정밀도를 가지며 일반적으로 높은 정확도가 필요한 금융 응용 프로그램 내에서 사용됩니다. 십진수는 double / float보다 훨씬 느립니다 (일부 테스트에서는 20 배까지).

십진수와 부동 소수점 / 복식은 캐스트없이 비교할 수 있지만 부동 소수점 수와 복식 수는 비교할 수 있습니다. 십진수는 또한 인코딩 또는 후미 0을 허용합니다.

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

결과 :

float: 0.3333333  
double: 0.333333333333333  
decimal: 0.3333333333333333333333333333
계산기 속도 0.1

.NET에서 decimal , floatdouble 의 차이점은 무엇입니까?

누군가이 중 하나를 언제 사용합니까?




+---------+----------------+---------+----------+---------------------------------------------+
| C#      | .Net Framework | Signed? | Bytes    | Possible Values                             |
| Type    | (System) type  |         | Occupied |                                             |
+---------+----------------+---------+----------+---------------------------------------------+
| sbyte   | System.Sbyte   | Yes     | 1        | -128 to 127                                 |
| short   | System.Int16   | Yes     | 2        | -32768 to 32767                             |
| int     | System.Int32   | Yes     | 4        | -2147483648 to 2147483647                   |
| long    | System.Int64   | Yes     | 8        | -9223372036854775808 to 9223372036854775807 |
| byte    | System.Byte    | No      | 1        | 0 to 255                                    |
| ushort  | System.Uint16  | No      | 2        | 0 to 65535                                  |
| uint    | System.UInt32  | No      | 4        | 0 to 4294967295                             |
| ulong   | System.Uint64  | No      | 8        | 0 to 18446744073709551615                   |
| float   | System.Single  | Yes     | 4        | Approximately ±1.5 x 10-45 to ±3.4 x 1038   |
|         |                |         |          |  with 7 significant figures                 |
| double  | System.Double  | Yes     | 8        | Approximately ±5.0 x 10-324 to ±1.7 x 10308 |
|         |                |         |          |  with 15 or 16 significant figures          |
| decimal | System.Decimal | Yes     | 12       | Approximately ±1.0 x 10-28 to ±7.9 x 1028   |
|         |                |         |          |  with 28 or 29 significant figures          |
| char    | System.Char    | N/A     | 2        | Any Unicode character (16 bit)              |
| bool    | System.Boolean | N/A     | 1 / 2    | true or false                               |
+---------+----------------+---------+----------+---------------------------------------------+

자세한 내용은 다음을 참조하십시오.
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/921a8ffc-9829-4145-bdc9-a96c1ec174a5




아무도 그것을 언급하지 않았다.

기본 설정에서 Floats (System.Single) 및 double (System.Double)은 오버플로 검사를 사용하지 않지만 Decimal (System.Decimal)은 항상 오버플로 검사를 사용합니다.

내말은

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

OverflowException을 던집니다.

그러나 이것들은 :

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

&

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



  1. double과 float는 컴파일과 실행시 모두 예외없이 정수로 나눌 수 있습니다.
  2. 소수는 정수 0으로 나눌 수 없습니다. 컴파일하면 컴파일이 실패합니다.



이것은 나에게 흥미로운 스레드였습니다. 오늘은 float decimal 보다 정밀도가 떨어지는 decimal 대한 불쾌한 버그가있었습니다.

C # 코드에서는 Excel 스프레드 시트에서 숫자 값을 읽고 decimal 로 변환 한 다음 decimal 다시 서비스로 보내 SQL Server 데이터베이스에 저장합니다.

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

이제 거의 모든 Excel 값에 대해이 작업이 훌륭하게 수행되었습니다. 그러나 일부에서는 매우 작은 Excel 값이 decimal.TryParse 사용하여 값을 완전히 잃었습니다. 그러한 예가있다.

  • cellValue = 0.00006317592

  • Decimal.TryParse (cellValue.ToString (), out value); // 0 을 반환합니다.

이 솔루션은 기괴하게도 Excel 값을 double 으로 변환 한 다음 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;
    …
}

doubledecimal 보다 정밀도가 떨어지지 만 작은 수는 여전히 인식됩니다. 어떤 이유로 double.TryParse 는 사실 작은 숫자를 검색 할 수 있지만 decimal.TryParse 는 0으로 설정합니다.

이상한. 매우 이상합니다.




메모리와 성능이 중요한 게임 및 임베디드 시스템과 같은 애플리케이션의 경우 float은 일반적으로 두 배보다 빠르고 크기가 크기 때문에 숫자 유형으로 선택됩니다. 정수는 이전에는 선택의 무기 였지만 부동 소수점 성능은 현대 프로세서에서 정수를 따라 잡았습니다. 10 진수가 바로 나온다!




이 모든 유형의 문제는 특정 부정확성이 존속하며 다음 예제와 같이 작은 십진수로이 문제가 발생할 수 있다는 것입니다

Dim fMean as Double = 1.18
Dim fDelta as Double = 0.08
Dim fLimit as Double = 1.1

If fMean - fDelta < fLimit Then
    bLower = True
Else
    bLower = False
End If

질문 : bLower 변수에는 어떤 값이 포함됩니까?

답변 : 32 비트 컴퓨터에서 bLower는 TRUE를 포함합니다 !!!

Double by Decimal을 대체하면 bLower에 좋은 대답 인 FALSE가 포함됩니다.

이중에서 문제는 fMean-fDelta = 1.09999999999가 1.1보다 낮다는 것입니다.

주의 : Decimal은 정밀도가 더 높은 두 배이고 정밀도는 항상 한도이기 때문에 동일한 문제가 다른 수에 대해 확실히 존재할 수 있다고 생각합니다.

실제로, Double, Float 및 Decimal은 COBOL의 BINARY 십진수에 해당합니다!

COBOL에서 구현 된 다른 숫자 유형이 .Net에 존재하지 않는 것은 유감입니다. COBOL을 모르는 사람들을 위해 COBOL에는 숫자 형 다음에 존재합니다.

BINARY or COMP like float or double or decimal
PACKED-DECIMAL or COMP-3 (2 digit in 1 byte)
ZONED-DECIMAL (1 digit in 1 byte) 



이들 각각의 주요 차이점은 정밀도입니다.

float32-bit 숫자이고 double64-bit 숫자이고 decimal128-bit 숫자입니다.




Related