在我的iOS swift应用程序中,我从网上收到一些json,其中包含一些代表货币的双值。它看起来像这样:
[{"Amount": 5.0},{"Amount":-26.07},{"Amount": 4}, ...etc]
我将这些转换为Doubles,然后尝试将这些值作为Swift“Double”提供给NSDecimalNumber的构造函数,如下所示:
let amount = NSDecimalNumber(double: amountAsDouble)
我遇到了这种方法的问题,因为我创建的NSDecimalNumber经常包含一个不同的数字,通过小数点16位。
let amount = NSDecimalNumber(double: -15.97)
println(amount)
返回-15.970000000000004096
我不想要这个,我想要-15.97。 谢谢,
答案 0 :(得分:1)
我最近为自己做了这件事。我最终使用NSNumberFormatter来获得正确的小数位。
let currFormatter = NSNumberFormatter()
currFormatter.numberStyle = .DecimalStyle
currFormatter.roundingIncrement = 0.01
currFormatter.minimumFractionDigits = 2
currFormatter.maximumFractionDigits = 2
let doubleAmount = currFormatter.numberFromString(amountAsDouble) as NSNumber!
let amount = doubleAmount as Double
println(amount)
答案 1 :(得分:1)
这里有一个提示:如果您使用NSJSONSerializer,带小数点的数字实际上会转换为NSDecimalNumber。 NSDecimalNumber是NSNumber的子类。那么你在做什么:你有一个非常好的NSDecimalNumber,将值四舍五入到双倍,并尝试将双重转回NSDecimalNumber。只要检查一下你的确是一个NSDecimalNumber,如果是的话就不进行转换。
答案 2 :(得分:0)
这是因为中间双重表示导致问题。
您应该将字典中的值作为NSString
个对象,并使用+ decimalNumberWithString:
方法进行转换而不会丢失精度。在swift:
let amount = NSDecimalNumber(string: amountAsString)
答案 3 :(得分:0)
Double
以18位十进制数字存储,您无法做任何事情,它是如何运作的。
请在此处阅读:http://en.wikipedia.org/wiki/Double-precision_floating-point_format
但是,在屏幕上显示值时,您可以像这样使用NSNumberFormatter
:
let amountInDouble: Double = -15.970000000000004096
let formatter = NSNumberFormatter()
formatter.numberStyle = .DecimalStyle
formatter.roundingIncrement = 0.01
formatter.maximumFractionDigits = 2
let amountAsString = formatter.stringFromNumber(NSNumber(double: amountInDouble))
if let amountAsString = amountAsString {
println(amountAsString) // -15.97
}
答案 4 :(得分:-1)
let amount = NSDecimalNumber.init(value: -15.97)
let roundValue = amount.rounding(accordingToBehavior: NSDecimalNumberHandler(roundingMode: .bankers, scale: 2, raiseOnExactness: false, raiseOnOverflow: false, raiseOnUnderflow: false, raiseOnDivideByZero: false))
print(roundValue)