2017-11-16 4 views
1

문서 here에 따르면 스위프트 3/4 십진법 유형은 밑이 10 인 NSDecimalNumber에 대한 표현입니다. 그러나 NSDecimalNumber를 사용할 때 재생산하지 않는 정밀한 문제가 있습니다.스위프트의 십진법 정밀도 문제

let dec24 = Decimal(integerLiteral: 24) 
let dec1 = Decimal(integerLiteral: 1) 
let decResult = dec1/dec24*dec24 
// prints 0.99999999999999999999999999999999999984 

let dn24 = NSDecimalNumber(value: 24) 
let dn1 = NSDecimalNumber(value: 1) 
let dnResult = dn1.dividing(by: dn24).multiplying(by: dn24) 
// prints 1 

Decimal 구조체가 정확하지 않거나 내가 잘못 이해해야합니까?

+0

인쇄 할 때 문제의 번호가 표시되는 방식이 아니라고 확인 했습니까? –

답변

4

NSDecimalNumber (및 오버레이 유형 Decimal)

can represent ... mantissa 38 자리까지 진수 정수 mantissa x 10^exponent 같이 표현 될 수있는 임의의 수, exponent는 -128의 정수이고

127 내지 따라서 십진 분수 (최대 38 진수)와 가 정확하게 표시 될 수 있지만, 임의의 플레이하지 mbers. 특히 1/24 = 0.416666666... 에는 십진수 (repeating decimal)가 무한하며 은 정확히 Decimal으로 표시 할 수 없습니다.

또한 DecimalNSDecimalNumber 사이에는 정밀도 차이가 없습니다. 우리가 실제 결과와 "이론적 인 결과"사이의 차이 를 인쇄하면 그건 분명해집니다 :

let dec24 = Decimal(integerLiteral: 24) 
let dec1 = Decimal(integerLiteral: 1) 
let decResult = dec1/dec24*dec24 

print(decResult - dec1) 
// -0.00000000000000000000000000000000000016 


let dn24 = NSDecimalNumber(value: 24) 
let dn1 = NSDecimalNumber(value: 1) 
let dnResult = dn1.dividing(by: dn24).multiplying(by: dn24) 

print(dnResult.subtracting(dn1)) 
// -0.00000000000000000000000000000000000016 
+1

여기서 질문은 왜 'Decimal'으로'0.9999999 ... '가 나오는지, NSDecimalNumber'로는 '1'이 나오는 이유에 관한 것입니다. 이것이 인쇄 방법의 차이 일뿐입니다. –

+0

@ItaiFerber 0.999999 .... 내 테스트에서 두 버전이 있습니다. –

+1

@ItaiFerber : OP 질문 * "Decimal 구조체가 정확하지 않아야합니까? ..."* 그 대답을하려고합니다. –

3

문제는 단순히 방법 놀이터 형식 번호의 유물이다.

난 놀이터 제 2 연산에 대한 제 계산 0.99999999999999999999999999999999999984 1과 같이 오른쪽에 번호가 표시
import Foundation 

let dn1 = Decimal(integerLiteral: 1) 
let dn24 = Decimal(integerLiteral: 24) 
let decResult = dn1/dn24 * dn24 
print(decResult) 

let nsdn1 = NSDecimalNumber(value: 1) 
let nsdn24 = NSDecimalNumber(value: 24) 

let nsdecResult = nsdn1.dividing(by: nsdn24).multiplying(by: nsdn24) 
print(nsdecResult) 

놀이터

이것을 입력. 그러나 두 인쇄 문은 0.99999999999999999999999999999999999984으로 인쇄되었습니다. 계산이 1/24이 정확히 표현할 수없는 (마틴 R 말한대로) 때문에 대신 10.99999999999999999999999999999999999984가 발생하는 이유

enter image description here

아, 그리고 그 이유를 다음과 같습니다

그것을 증명하는 사진입니다 Decimal.