.net - 차이 - 부동소수점




.NET에서 decimal, float 및 double의 차이점은 무엇입니까? (11)

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

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


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

Decimal 구조는 정확성을 요구하는 재무 계산에 엄격하게 맞추어지며, 반올림을 상대적으로 허용하지 않습니다. 그러나 몇 가지 이유로 과학 응용 분야에 소수가 적합하지 않습니다.

  • 물리적 인 문제 또는 측정되는 인공물의 실질적인 한계 때문에 많은 과학 계산에서 일정한 정밀도의 손실이 허용됩니다. 정밀도 상실은 금융 분야에서 허용되지 않습니다.
  • 십진수는 부동 소수점 연산이 이진수로 수행되기 때문에 십진법은 부동 소수점 연산이 기본 10에서 수행되는 반면 부동 소수점 연산은 MMX / SSE와 같은 FPU 하드웨어에서 처리됩니다. 소수는 소프트웨어에서 계산됩니다).
  • Decimal은 더 많은 정밀도를 지원한다는 사실에도 불구하고 double보다 용납 할 수없는 작은 값 범위를가집니다. 따라서 Decimal은 많은 과학적 가치를 나타 내기 위해 사용할 수 없습니다.

간단한 단어로 :

  1. Decimal, Double 및 Float 변수 유형은 값을 저장하는 방식이 다릅니다.
  2. 부동 소수점 은 단일 정밀도 (32 비트) 부동 소수점 데이터 유형이고 double 은 배정도 (64 비트) 부동 소수점 데이터 유형이며 소수점 은 128 비트입니다. 부동 소수점 데이터 형식
  3. 요약 표 :

/==========================================================================================
    Type       Bits    Have up to                   Approximate Range 
/==========================================================================================
    float      32      7 digits                     -3.4 × 10 ^ (38)   to +3.4 × 10 ^ (38)
    double     64      15-16 digits                 ±5.0 × 10 ^ (-324) to ±1.7 × 10 ^ (308)
    decimal    128     28-29 significant digits     ±7.9 x 10 ^ (28) or (1 to 10 ^ (28)
/==========================================================================================
여기 , Float , DoubleDecimal 더 읽을 수 있습니다.


나는 다른 답변과 코멘트에서 이미 대답 한 좋은 (그리고 나쁜 정보) 톤을 반복하지는 않겠지 만 다음 질문에 대한 답변을 드릴 것입니다 :

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

카운트 된 값에는 십진수를 사용하십시오.

측정 값에 float / double 사용

몇 가지 예 :

  • 돈 (우리가 돈을 계산하거나 돈을 측정합니까?)

  • 거리 (거리 또는 거리를 계산합니까? *)

  • 점수 (점수를 집계합니까? 아니면 점수를 계산합니까?)

우리는 항상 돈을 계산하고 그것을 측정해서는 안됩니다. 우리는 보통 거리를 측정합니다. 우리는 종종 점수를 계산합니다.

* 어떤 경우에는, 내가 명목 거리 라고 부르는 것, 실제로 거리를 '계산'할 수 있습니다. 예를 들어, 우리는 도시와의 거리를 나타내는 국가 기호를 다루고 있으며, 그 거리가 십진수 한자리 (xxx.xkm)를 초과 할 수 없다는 것을 알고 있습니다.


부동 ± ~ 1.5 x 10-45 ~ ± 3.4 x 1038 -------- 7 숫자
두 배 ~ ± 5.0 x 10-324 ~ ± 1.7 x 10308 ------ 15 또는 16 자
십진수 ~ ± 1.0 x 10-28 ~ ± 7.9 x 1028 -------- 28 또는 29 자


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

기본 설정에서 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;

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

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) 

이것은 나에게 흥미로운 스레드였습니다. 오늘은 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으로 설정합니다.

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


정밀도 7 자리 float

double 에는 약 15 자리의 정밀도가 있습니다.

decimal 는 약 28 자리의 정밀도를가집니다.

정확도가 더 필요하면 float 대신 double을 사용하십시오. 최신 CPU에서는 두 데이터 유형이 거의 동일한 성능을 보입니다. float를 사용하는 유일한 방법은 공간을 적게 차지하는 것입니다. 실질적으로 당신이 그들 중 많은 것을 가지고있는 경우에만 중요합니다.

나는 이것이 흥미 롭다는 것을 알았다. 모든 컴퓨터 과학자가 부동 소수점 산술에 대해 알아야 할 사항


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

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

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





decimal