Не использовать поплавки или двойников представлять валюту, именно по (каламбур) по этой причине. Вместо этого используйте NSDecimalNumber (см. Which Swift datatype do I use for currency).
NSDecimalNumber прилагает определенные усилия для использования, но выполняет арифметику базы 10. Чтобы использовать его правильно, вам нужно немного почитать API. В частности, для округления вам нужно предоставить NSDecimalNumberHandler (вы можете установить значение по умолчанию для использования).
Хороший материал для чтения:
Я думаю что площадка показывает неожиданный результат потому что он принуждает внутреннее значение NSDecimalNumber к Double bef (я бы приветствовал альтернативные или авторитетные объяснения, потому что я нахожу это любопытным). Однако внутреннее представление должно быть правильным.
Попробуйте это в Playground:
let myRoundingBehavior = NSDecimalNumberHandler(roundingMode: .RoundBankers,
scale: 2, raiseOnExactness: true, raiseOnOverflow: true, raiseOnUnderflow: true, raiseOnDivideByZero: true)
NSDecimalNumber.setDefaultBehavior(myRoundingBehavior)
let integerPrice = NSDecimalNumber(mantissa: 987, exponent: -2, isNegative: false)
integerPrice // 9.870000000000001
Float(integerPrice) // 9.87
Double(integerPrice) // 9.870000000000001
integerPrice.description // "9.87"
Не думайте, что Float является более точным представлением числа, это просто происходит работать лучше. Если вы держите свои расчеты (например, налоги, скидка, доставка и т. Д.) В области NSDecimalNumber, они будут точными.
Swift 3/Xcode бета 1 бонус:
поведение площадка остается прежним, но меняется Великий API ереименование Rodeo изменяет приведенный выше код:
let myRoundingBehavior = NSDecimalNumberHandler(roundingMode: .roundBankers,
scale: 2,
raiseOnExactness: true,
raiseOnOverflow: true,
raiseOnUnderflow: true,
raiseOnDivideByZero: true)
Изменение здесь что глобальное перечисление NSRoundingMode исчезает и заменяется перечислением RoundingMode, которое является членом NSDecimalNumber.
Это значения с плавающей запятой для вас. :) http://programmers.stackexchange.com/questions/101163/what-causes-floating-point-rounding-errors –
Вам нужно сгенерировать новые токены, если они являются частными. Вы включили их в выходной образец. – Brett