Математическая ошибка NSDecimalNumber в глубоких десятичных дробях

У меня есть расширение Swift на NSDecimalNumber:

extension NSDecimalNumber {

    var asRawValue: NSDecimalNumber {
        return self.multiplying(byPowerOf10: 30)
    }

}

И тест:

let t = NSDecimalNumber(value: 335).asRawValue
let u = NSDecimalNumber(value: 0.00001).asRawValue

// fails
XCTAssert(t.subtracting(u).compare((NSDecimalNumber(value: 334.99999)).asRawValue) == .orderedSame)

// console 
po NSDecimalNumber(value: 334.99999).asRawValue
334999990000000051200000000000000

Почему в середине длинного хвоста нулей моего NSDecimalNumber есть случайное число 512? Как мне избежать этого, чтобы я мог полагаться на математику очень малых чисел?

Спасибо


person Zack Shapiro    schedule 18.01.2018    source источник
comment
334.99999 это Double. И это значение не является точным, как Double.   -  person rmaddy    schedule 18.01.2018
comment
О, это было моим плохим?   -  person Zack Shapiro    schedule 18.01.2018
comment
Вы можете создать NSDecimalNumber из String: po NSDecimalNumber(string: "334.99999").asRawValue   -  person rmaddy    schedule 18.01.2018
comment
Это связано с пунктом 2 в моем ответе на другой ваш вопрос: 334.99999 Double не может быть представлено точно в десятичном виде, и, следовательно, имеет ограничение в 16 значащих цифр Double. Однако, если вы используете NSDecimalNumber(mantissa: 33499999, exponent: -5, isNegative: false), это может быть. В итоге прекратите передавать значения с плавающей запятой в NSDecimalNumber (или Decimal), и вы не увидите артефактов такого рода.   -  person Rob    schedule 18.01.2018