우리는 최근 여러 통화로 값을 처리하고 그 사이에서 변환 해야하는 시스템을 구현했으며 어려운 몇 가지 사항을 알아 냈습니다.
돈에 부동 소수점 숫자를 사용하지 마십시오
부동 소수점 산술은 무언가를 망칠 때까지 눈에 띄지 않을 수있는 부정확성을 소개합니다. 모든 값은 정수 또는 고정 소수점 형식으로 저장해야하며, 고정 소수점 형식을 사용하기로 선택한 경우 해당 형식이 후드에서 수행하는 작업을 정확히 이해해야합니다 (예 : 내부적으로 정수 또는 부동 소수점을 사용합니까) 유형).
계산 또는 변환이 필요한 경우 :
- 값을 부동 소수점으로 변환
- 새로운 가치를 계산
- 숫자를 반올림하고 다시 정수로 변환
3 단계에서 부동 소수점 숫자를 다시 정수로 변환 할 때는 캐스트하지 말고 수학 함수를 사용하여 먼저 반올림하십시오. round
특별한 경우에는 floor
또는 일 수 있지만 이것은 보통 일 것이다 ceil
. 차이점을 알고 신중하게 선택하십시오.
값과 함께 숫자 유형을 저장하십시오.
하나의 통화 만 처리하는 경우에는 이것이 중요하지 않을 수 있지만 여러 통화를 처리하는 데 중요했습니다. USD, GBP, JPY, EUR 등과 같은 통화에 3 자 코드를 사용했습니다.
상황에 따라 다음을 저장하는 것이 도움이 될 수도 있습니다.
- 숫자가 세전 또는 후인지 여부 및 세율
- 숫자가 변환의 결과인지 여부 및 변환 된 결과
당신이 다루고있는 숫자의 정확도 한계를 아십시오
실제 가치의 경우 가장 작은 통화 단위만큼 정확해야합니다. 이것은 1 센트, 1 페니, 엔, 펜 등의 값이 없다는 것을 의미합니다. 아무 이유없이 그 값보다 높은 정확도로 값을 저장하지 마십시오.
내부적으로 더 작은 값을 처리하도록 선택할 수 있으며,이 경우 다른 통화 값 유형입니다 . 코드가 어느 것을 알고 있고 혼동하지 않도록하십시오. 여기에서도 부동 소수점 값을 사용하지 마십시오.
이러한 규칙을 모두 추가하여 다음 규칙을 결정했습니다. 실행 코드에서 통화는 가장 작은 단위의 정수를 사용하여 저장됩니다.
class Currency {
String code; // eg "USD"
int value; // eg 2500
boolean converted;
}
class Price {
Currency grossValue;
Currency netValue;
Tax taxRate;
}
데이터베이스에서 값은 다음 형식으로 문자열로 저장됩니다.
USD:2500
그것은 $ 25.00의 가치를 저장합니다. 통화를 처리하는 코드가 데이터베이스 계층 자체 내에있을 필요가 없으므로 모든 값을 먼저 메모리로 변환 할 수 있기 때문에 그렇게 할 수있었습니다. 다른 상황은 의심 할 여지없이 다른 솔루션에 적합합니다.
그리고 내가 일찍 그것을 명확하게 하지 않은 경우, float을 사용하지 마십시오!