더블은 정말 돈에 부적합합니까?
나는 항상 C #에서 double 유형의 변수가 돈에 적합하지 않다고 말합니다. 모든 이상한 일이 일어날 수 있습니다. 그러나 이러한 문제 중 일부를 보여주는 예제를 만들 수없는 것 같습니다. 누구든지 그러한 예를 제공 할 수 있습니까?
(편집;이 게시물은 원래 C # 태그가 지정되었습니다. 일부 답변은의 특정 세부 정보를 참조 decimal
하므로을 의미합니다 System.Decimal
).
(편집 2 : 나는 특정 C # 코드를 요청했기 때문에 이것이 언어에 구애받지 않는다고 생각하지 않습니다)
아주, 아주 부적합합니다. 십진수를 사용하십시오.
double x = 3.65, y = 0.05, z = 3.7;
Console.WriteLine((x + y) == z); // false
( 여기 Jon의 페이지 예 -권장 읽기 ;-p)
반올림으로 인해 효과적으로 이상한 오류가 발생합니다. 또한 정확한 값과의 비교는 매우 까다 롭습니다. 일반적으로 특정 값에 "가까운"실제 값이 있는지 확인하기 위해 일종의 엡실론을 적용해야합니다.
다음은 구체적인 예입니다.
using System;
class Test
{
static void Main()
{
double x = 0.1;
double y = x + x + x;
Console.WriteLine(y == 0.3); // Prints False
}
}
예, 부적합합니다.
double에 약 17 개의 유효 숫자가 있음을 올바르게 기억하면 일반적으로 반올림 오류가 소수점 뒤에서 발생합니다. 대부분의 금융 소프트웨어는 소수점 뒤에 소수점 4 자리를 사용하기 때문에 소수점 이하 13 자리를 사용할 수 있으므로 단일 작업에 사용할 수있는 최대 숫자는 여전히 미국 국가 부채보다 훨씬 높습니다. 그러나 반올림 오류는 시간이 지남에 따라 추가됩니다. 소프트웨어가 오랫동안 실행되면 결국 센트를 잃기 시작합니다. 특정 작업은 상황을 악화시킵니다. 예를 들어 소량에 많은 양을 추가하면 정밀도가 크게 떨어집니다.
돈 운영을 위해 고정 소수점 데이터 유형이 필요합니다. 대부분의 사람들은 여기저기서 1 센트를 잃어도 상관하지 않지만 회계사는 대부분의 사람들과 다릅니다.
편집
이 사이트에 따르면 http://msdn.microsoft.com/en-us/library/678hzkk9.aspx Doubles는 실제로 17이 아닌 15-16 개의 유효 숫자를가집니다.
@Jon Skeet 십진수는 더 높은 정밀도, 28 또는 29 개의 유효 소수 때문에 double보다 더 적합합니다. 이는 누적 된 반올림 오류가 심각해질 가능성이 적다는 것을 의미합니다. Boojum 언급과 같은 고정 소수점 데이터 유형 (예 : 내가 사용한 것처럼 센트 또는 100 분의 1 센트를 나타내는 정수)이 실제로 더 적합합니다.
decimal
10 배의 배율을 사용하기 때문에 0.1과 같은 숫자를 정확하게 표현할 수 있습니다. 본질적으로 십진수 유형은 이것을 1/10 ^ 1로 double
나타내고 a 는 이것을 104857/2 ^ 20으로 나타냅니다 (실제로는 정말 큰 숫자 / 2 ^ 1023에 가깝습니다).
A decimal
는 최대 28/29 개의 유효 자릿수 (예 : 0.1)로 모든 기본 10 값을 정확하게 나타낼 수 있습니다. A double
는 할 수 없습니다.
내 이해는 대부분의 금융 시스템은 정수를 사용하여 통화를 표현한다는 것입니다. 즉, 모든 것을 센트로 계산합니다.
IEEE 배정 밀도는 실제로 -2 ^ 53에서 + 2 ^ 53 범위의 모든 정수를 정확하게 나타낼 수 있습니다 . (Hacker 's Delight, pg. 262) 덧셈, 뺄셈, 곱셈 만 사용하고 모든 것을이 범위 내에서 정수로 유지한다면 정밀도 손실이 없어야합니다. 그러나 나는 분열이나 더 복잡한 작업에 대해 매우 조심할 것입니다.
당신이 무엇을하고 있는지 모를 때 double을 사용하는 것은 부적합합니다.
"double"은 1/90 센트의 오류로 1 조 달러의 금액을 나타낼 수 있습니다. 따라서 매우 정확한 결과를 얻을 수 있습니다. 화성에 사람을 태우고 다시 살리는 데 드는 비용을 계산하고 싶습니까? double은 잘 할 것입니다.
그러나 돈에는 특정 계산이 특정 결과를 제공하고 다른 결과는 제공하지 않아야한다는 매우 구체적인 규칙이 종종 있습니다. 당신은 종종 결과가 $ 98.14 또는 $ 98.13해야하고 여부를 결정하는 규칙이있을 것이다 아주 아주 아주 가까운 $ 98.135에있는 양을 계산하면 해야한다 그 규칙을 따르고 필요한 결과를 얻을 수 있습니다.
거주 지역에 따라 64 비트 정수를 사용하여 센트, 페니 또는 코펙 또는 해당 국가에서 가장 작은 단위를 나타내는 것이 일반적으로 잘 작동합니다. 예를 들어, 센트를 나타내는 64 비트 부호있는 정수는 최대 92,223 조 달러의 값을 나타낼 수 있습니다. 32 비트 정수는 일반적으로 적합하지 않습니다.
double에는 항상 반올림 오류가 없습니다. .Net을 사용하는 경우 "decimal"을 사용합니다.
실제로 부동 소수점 double 은 적절한 단위를 선택하는 한 금액을 나타내는 데 완벽하게 적합합니다.
참조 http://www.idinews.com/moneyRep.html를
따라서 고정 소수점 길이 입니다. 어느 쪽이든 8 바이트를 소비하는데, 십진수 항목이 소비하는 16 바이트보다 확실히 더 좋습니다 .
어떤 것이 작동하는지 여부 (예 : 예상되고 올바른 결과를 산출 함)는 투표 또는 개인 선호도의 문제가 아닙니다. 기술이 작동하거나 작동하지 않습니다.
참고 URL : https://stackoverflow.com/questions/316727/is-a-double-really-unsuitable-for-money
'IT TIP' 카테고리의 다른 글
PHP에서 비트 마스크를 구현하는 방법은 무엇입니까? (0) | 2020.11.03 |
---|---|
ActionBar 위쪽 탐색은 onResume 대신 부모 활동을 다시 만듭니다. (0) | 2020.11.03 |
int의 크기는 컴파일러 및 / 또는 프로세서에 따라 달라 집니까? (0) | 2020.11.03 |
JavaScript : 숫자의 n 번째 근을 계산합니다. (0) | 2020.11.03 |
해석 모드에서 하스켈 파일을 실행하는 방법 (0) | 2020.11.03 |