무엇 사이의 차이 decimal
, float
그리고 double
.NET에?
누군가이 중 하나를 언제 사용합니까?
무엇 사이의 차이 decimal
, float
그리고 double
.NET에?
누군가이 중 하나를 언제 사용합니까?
답변:
float
하고 double
있습니다 부동 이진 소수점 형식을 . 즉, 다음과 같은 숫자를 나타냅니다.
10001.10010110011
이진수와 이진수의 위치는 모두 값 내에 인코딩됩니다.
decimal
A는 부동 소수점 포인트 유형 . 즉, 다음과 같은 숫자를 나타냅니다.
12345.65789
다시 말하지만, 소수점 의 숫자와 위치 는 모두 값 내에 인코딩됩니다 decimal
. 이것이 고정 소수점 유형 대신 부동 소수점 유형을 만드는 것입니다.
주의해야 할 중요한 점은 인간은 정수가 아닌 정수를 10 진수 형식으로 나타내는 데 사용되며 10 진수로 정확한 결과를 기대한다는 것입니다. 모든 소수를 이진 부동 소수점 (예 : 0.1)으로 정확하게 표현할 수있는 것은 아닙니다. 따라서 이진 부동 소수점 값을 사용하면 실제로는 대략 0.1이됩니다. 부동 소수점을 사용할 때도 근사값을 얻을 수 있습니다. 예를 들어 1을 3으로 나눈 결과는 정확하게 표현할 수 없습니다.
언제 사용 하는가에 관해서 :
"자연스럽게 정확한 소수"인 값의 경우을 사용하는 것이 좋습니다 decimal
. 이것은 일반적으로 인간이 발명 한 모든 개념에 적합합니다. 재무 가치가 가장 분명한 예이지만 다른 것도 있습니다. 예를 들어 다이버 나 아이스 스케이터에게 주어진 점수를 고려하십시오.
정말 측정 할 수없는 성격의 많은 유물입니다 값에 대해서는 정확히 어쨌든, float
/ double
더 적합합니다. 예를 들어 과학 데이터는 일반적으로이 형식으로 표시됩니다. 여기서 원래 값은 "소수 적으로 정확"하지 않으므로 예상 결과가 "소수 정확도"를 유지하는 것은 중요하지 않습니다. 부동 이진 소수점 유형은 소수보다 작업 속도가 훨씬 빠릅니다.
float
/ double
일반적으로 숫자를 나타내는 것으로 나타내지 않습니다 101.101110
. 일반적으로 1101010 * 2^(01010010)
지수 와 같은 것으로 나타납니다
float
으며 C # 별칭 키워드이며 .Net 유형 이 아닌 것이 놀랍습니다 . 그건 System.Single
.. single
및 double
이진 소수점 형식을 떠 있습니다.
주요 차이점은 정밀성입니다.
부동 -7 자리 (32 비트)
더블 -15-16 자리 (64 비트)
10 진수 -28-29 유효 숫자 (128 비트)
십진법은 정밀도가 훨씬 높으며 일반적으로 높은 정확도를 요구하는 금융 응용 프로그램에서 사용됩니다. 십진법은 더블 / 플로트보다 훨씬 느립니다 (일부 테스트에서는 최대 20 배).
십진법과 실수 / 더블은 캐스트없이 비교할 수 없지만 부유물과 복식은 비교할 수 없습니다. 10 진수는 인코딩 또는 후행 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
– 그것은 실제 세계에서는 거의 그렇지 않습니다! 모든 유한의 저장 형식은 비트 패턴의 한정된 수의 가능한 값의 수를 무한 conflate 것이다. 예를 들어, float
conflate 것 0.1
과 0.1 + 1e-8
동시에, decimal
conflate 것 0.1
하고 0.1 + 1e-29
. 물론, 주어진 범위 내에서 , 특정 값은 정확도 손실이없는 모든 형식으로 표현 될 수 있습니다 (예 : 정확도 손실이없는 상태에서 float
최대 1.6e7의 정수를 저장할 수 있음). 그러나 여전히 무한 정확도 는 아닙니다 .
0.1
가 아닙니다 ! 수있는 유일한 방법 0.1
보다 "더 나은" 0.10000001
때문입니다 인간 베이스 (10) 그리고 심지어와 같은 float
당신이 두 값을 초기화 할 경우 값이 0.1
같은 방식으로, 그들은 모두 같은 값이됩니다 . 그것은 단지 그 값이 정확 하지 않다는 것입니다. 0.1
그것은 정확히로 표현 될 수 있는 가장 가까운 값0.1
float
입니다. 물론, 이진 수레가 (1.0 / 10) * 10 != 1.0
있지만 십진 수레 수가 (1.0 / 3) * 3 != 1.0
있습니다. 어느 쪽 도 완벽 하지는 않습니다 .
double a = 0.1; double b = 0.1;
그렇다면 a == b
사실이 될 것이다 . 그것은 단지의 a
및 b
것 모두 정확히 동일하지 0.1
. C #에서, 당신이 할 경우 decimal a = 1.0m / 3.0m; decimal b = 1.0m / 3.0m;
다음 a == b
도 마찬가지 일 것이다. 그러나이 경우, 어느 쪽 의 a
도는 b
것입니다 정확히 동일 1/3
- 그들은 것 모두 동일 0.3333...
. 에서 둘 경우, 일부 정확도는 표현으로 인해 손실됩니다. 당신은 완고하게 decimal
"무한"정밀도 를 가지고 있다고 말하는데 , 그것은 거짓 입니다.
Decimal 구조는 정확성을 요구하는 재무 계산에 엄격하게 맞춰져 있으며, 이는 상대적으로 반올림을 허용하지 않습니다. 그러나 십진법은 몇 가지 이유로 과학적 응용에는 적합하지 않습니다.
+---------+----------------+---------+----------+---------------------------------------------+
| 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 |
+---------+----------------+---------+----------+---------------------------------------------+
다른 답변과 의견에 이미 답변 된 좋은 (그리고 일부 나쁜) 정보를 반복하지는 않지만 다음 질문에 대한 팁으로 답변 해 드리겠습니다.
누군가이 중 하나를 언제 사용합니까?
계산 된 값에 10 진수 사용
측정 값에 float / double 사용
몇 가지 예 :
돈 (돈을 세거나 돈을 측정합니까?)
거리 (거리를 세거나 거리를 측정합니까? *)
점수 (점수를 세거나 점수를 측정합니까?)
우리는 항상 돈을 세고 측정해서는 안됩니다. 우리는 보통 거리를 측정합니다. 우리는 종종 점수를 계산합니다.
* 경우에 따라 공칭 거리 라고 부르는 것은 실제로 거리를 계산하는 것이 좋습니다. 예를 들어, 도시까지의 거리를 나타내는 국가 표시를 처리하고있을 수 있으며 해당 거리는 10 진수 (xxx.xkm)를 초과하지 않습니다.
float
7 자리 정밀도
double
정밀도는 약 15 자리입니다.
decimal
정밀도는 약 28 자리입니다
더 나은 정확도가 필요하면 float 대신 double을 사용하십시오. 최신 CPU에서는 두 데이터 유형이 거의 동일한 성능을 갖습니다. float를 사용하는 유일한 이점은 공간을 덜 차지한다는 것입니다. 실제로 많은 것을 가지고있는 경우에만 중요합니다.
나는 이것이 재미 있다는 것을 알았다. 부동 소수점 산술에 대해 모든 컴퓨터 과학자가 알아야 할 사항
double
32 비트보다 큰 정수 유형을 사용할 수 double
없었고 53 비트 정수 유형 인 것처럼 사용 된 경우 (예 : 보유 )의 경우 회계 응용 프로그램에서 적절 하다고 생각합니다. 전체 동전, 또는 100 분의 1 센트의 정수). 오늘날 그러한 것들에는 많이 사용되지는 않지만 많은 언어는 64 비트 (또는 경우에 따라 32 비트!) 정수 수학을 얻기 전에 배정도 부동 소수점 값을 사용할 수 있습니다.
Real
IIRC는 단위 정밀도로 최대 1.8E + 19까지의 값을 나타낼 수 있는 Turbo-87 일 것입니다. 회계 응용 프로그램을 사용하는 것보다 훨씬 많은 Real
동전을 표현하는 데 훨씬 더 안전하다고 생각합니다 .
double
단위 정확도가 9E15까지 인 유형을 갖는 언어가 매우 일반적 이었습니다. 사용 가능한 가장 큰 정수 유형보다 큰 정수를 저장 해야하는 경우 double
, 특히 프로세서가 16x16-> 32를 수행하는 명령을 가지고 있지만 다중 정밀도 수학을 퍼지하는 것보다 간단하고 효율적입니다. ..
아무도 언급하지 않았습니다
기본 설정에서 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;
float.MaxValue+1 == float.MaxValue
마찬가지로 decimal.MaxValue+0.1D == decimal.MaxValue
. 아마도 당신은 같은 것을 의미 float.MaxValue*2
했습니까?
System.Decimal
이 전체 단위를 구별 할 수 없게 직전에 예외가 발생하지만, 응용 프로그램은 너무 늦을 수 있습니다 예를 들어, 달러와 센트를 처리하도록되어있는 경우.
decimal
을 0 으로 나누려고 하면 (CS0020) 컴파일 이 실패 하고 정수 리터럴의 경우에도 마찬가지입니다. 그러나 런타임 10 진수 값을 0으로 나누면 컴파일 오류가 아닌 예외가 발생합니다.
언급 한 바와 같이 정수는 정수입니다. .7, .42 및 .007과 같이 포인트를 저장할 수 없습니다. 정수가 아닌 숫자를 저장해야하는 경우 다른 유형의 변수가 필요합니다. double 형이나 float 형을 사용할 수 있습니다. 이러한 유형의 변수는 정확히 같은 방식으로 설정합니다. 단어를 사용하는 대신 또는 int
을 입력 합니다. 이처럼 :double
float
float myFloat;
double myDouble;
( float
"부동 소수점"의 줄임말이며 끝에 점이있는 숫자를 의미합니다.)
둘의 차이점은 보유 할 수있는 숫자의 크기입니다. 의 경우 float
최대 7 자리 숫자를 사용할 수 있습니다. 의 경우 double
최대 16 자리를 가질 수 있습니다. 보다 정확한 공식 크기는 다음과 같습니다.
float: 1.5 × 10^-45 to 3.4 × 10^38
double: 5.0 × 10^-324 to 1.7 × 10^308
float
32 비트 숫자이며 double
64 비트 숫자입니다.
코드를 보려면 새 버튼을 두 번 클릭하십시오. 버튼 코드에 다음 세 줄을 추가하십시오.
double myDouble;
myDouble = 0.007;
MessageBox.Show(myDouble.ToString());
프로그램을 중단하고 코딩 창으로 돌아갑니다. 이 줄을 바꾸십시오 :
myDouble = 0.007;
myDouble = 12345678.1234567;
프로그램을 실행하고 이중 버튼을 클릭하십시오. 메시지 상자에 번호가 올바르게 표시됩니다. 그러나 끝에 다른 숫자를 추가하면 C #이 다시 반올림 또는 내림됩니다. 도덕은 정확성을 원한다면 반올림에주의하십시오!
decimal
실제로 2 진수 형식과는 반대로 10 진수 형식으로 저장되므로 두 숫자 시스템 간의 변환으로 인해 숫자가 손실되거나 반올림되지 않습니다. 또한 decimal
NaN, -0, ∞ 또는 -∞과 같은 특수 값 개념이 없습니다.
오늘 우리는 a decimal
보다 정밀도가 떨어지는 것에 대해 불쾌한 작은 버그가 있었기 때문에 이것은 나에게 흥미로운 스레드였습니다 float
.
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 (), 출력 값); // 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;
…
}
double
보다 정밀도가 떨어지지 만 decimal
실제로는 적은 수를 인식 할 수 있습니다. 어떤 이유로, double.TryParse
실제로 작은 숫자를 검색 할 수 있었지만 decimal.TryParse
0으로 설정했습니다.
이상한. 매우 이상합니다.
decimal.Parse("0.00006317592")
작동합니다. 다른 일이 있습니다. -아마도 과학적 표기법?
메모리와 성능이 모두 중요한 게임 및 임베디드 시스템과 같은 응용 프로그램의 경우 float는 일반적으로 두 배의 절반 크기보다 빠르기 때문에 숫자 선택 유형입니다. 정수는 선택의 무기 였지만 부동 소수점 성능은 현대 프로세서에서 정수를 능가했습니다. 십진법이 바로입니다!
Decimal, Double 및 Float 변수 유형은 값을 저장하는 방식이 다릅니다. float는 단 정밀도 (32 비트) 부동 소수점 데이터 유형이고 double은 배정 밀도 (64 비트) 부동 소수점 데이터 유형이고 10 진수는 128 비트 부동 소수점 데이터 유형 인 경우 정밀도는 주요 차이점입니다.
부동-32 비트 (7 자리)
이중-64 비트 (15-16 자리)
10 진수-128 비트 (28-29 유효 숫자)
Decimal, Float 및 Double의 차이점 에 대한 자세한 내용
이러한 모든 유형의 문제점은 특정 부정확성이 존재하며이 예제는 다음 예제와 같이 작은 소수로 발생할 수 있다는 것입니다
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을 Decimal로 바꾸면 bLower에 FALSE가 포함되어 있습니다.
이중으로, 문제는 fMean-fDelta = 1.09999999999이며 1.1보다 낮습니다.
주의 : Decimal은 정밀도가 두 배이고 정밀도는 항상 한계가 있기 때문에 다른 숫자에도 동일한 문제가 존재할 수 있다고 생각합니다.
실제로 Double, Float 및 Decimal은 COBOL의 BINARY 10 진수에 해당합니다!
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)
간단히 말해서 :
/==========================================================================================
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 , Double 및 Decimal을 참조하십시오 .
Decimal
금융 애플리케이션에 적합하며 사이를 결정할 때 사용하는 주요 기준이다 Decimal
와 Double
. Double
예를 들어 정밀성이 과학 응용 분야에 충분하지 않은 경우는 드물며 제한적인 범위 때문에 과학 응용 분야 에는 적합하지 않은Decimal
경우가 많습니다 .
이들 각각의 주요 차이점은 정밀도입니다.
float
A는 32-bit
번호, double
A는 64-bit
번호와 decimal
A는 128-bit
번호입니다.
10 진수 128 비트 (28-29 유효 숫자) 재무 응용 프로그램의 경우 높은 수준의 정확도를 제공하고 반올림 오류를 피하기 때문에 10 진수 형식을 사용하는 것이 좋습니다. 정밀도가 필요한 경우 정수가 아닌 수학에는 10 진수를 사용하십시오 (예 : 돈과 통화)
이중 64 비트 (15-16 자리) 이중 유형은 비용 처리를 제외하고 실제 값에 가장 일반적으로 사용되는 데이터 유형입니다. 가장 정확한 답이 필요하지 않은 정수가 아닌 수학에는 double을 사용하십시오.
Float 32 비트 (7 자리) 주로 처리 능력에 대한 요구가 높고 반올림 오류를 견딜 수있는 상황이 발생하기 때문에 주로 그래픽 라이브러리에서 사용됩니다.
Decimals
보다 훨씬 느립니다 double/float
.
Decimals
및 Floats/Doubles
캐스트없이 비교할 수없는 반면 Floats
및Doubles
캔.
Decimals
인코딩 또는 후행 0도 허용합니다.