是我还是NSNumberFormatter坏了?

时间:2016-03-17 17:52:24

标签: ios swift nsnumber nsnumberformatter nsdecimalnumber

在Swift中,我想将String转换为可用于算术的NSDecimalNumber。

对于绝大多数情况,NSNumberFormatter.numberFromString()效果很好。但是,对于某些值,无论我如何尝试将解析后的数字转换为NSDecimalNumber,它都无法正常工作。

从我编写的一些游乐场代码中查看此输出(包含在下面)。它使用一个特定值来演示该问题:

numberString: 546000.06
numberFormatter.numberFromString(numberString): 546000.0600000001 //expected = 546000.06
number.decimalValue: NSDecimal(_mantissa: (34305, 29756, 26071, 19, 0, 0, 0, 0)) //Need NSDecimalNumber to convert to String, see below
number.doubleValue: 546000.06 //expected = 546000.06
number.floatValue: 546000.0 //expected = 546000.06
** number and numberString converted into NSDecimalNumber different ways **
NSDecimalNumber(string: numberString): 546000.06 //expected = 546000.06
NSDecimalNumber(decimal: number.decimalValue): 546000.0600000001 //expected = 546000.06
NSDecimalNumber(double: number.doubleValue): 546000.0600000001024 //expected = 546000.06
NSDecimalNumber(float: number.floatValue): 546000.0624999999488 //expected = 546000.06
** Add one to each NSDecimalNumber **
stringDecimalNumber+1: 546001.06 // expected = 546000.06+1
decimalDecimalNumber+1: 546001.0600000001 // expected = 546000.06+1
doubleDecimalNumber+1: 546001.0600000001024 // expected = 546000.06+1
floatDecimalNumber+1: 546001.0624999999488 // expected = 546000.06+1
** Formatted NSNumber and NSDecimalNumbers **
number formatted: 546,000.06
stringDecimalNumber formatted: 546,000.06
decimalDecimalNumber formatted: 546,000.0600000001
doubleDecimalNumber formatted: 546,000.0600000001
floatDecimalNumber formatted: 546,000.0624999999

似乎没有办法从NSNumberFormatter解析的NSNumber到达准确的NSDecimalNumber。有趣的是,将数字String直接传递给NSDecimalNumber构造函数似乎完美无缺。不幸的是,我不能这样做,因为在我的实际用例中,字符串是一种货币,所以我需要 NSNumberFormatter。

这里承诺的是生成上面输出的游乐场代码:

import Foundation

let numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = .DecimalStyle
numberFormatter.locale = NSLocale.currentLocale()
numberFormatter.maximumFractionDigits = 10

let numberString: String = "546000.06"

print("numberString: \(numberString)")

let number: NSNumber = numberFormatter.numberFromString(numberString)!
print("numberFormatter.numberFromString(numberString): \(number) //expected = \(numberString)")
print("number.decimalValue: \(number.decimalValue) //Need NSDecimalNumber to convert to String, see below")
print("number.doubleValue: \(number.doubleValue) //expected = \(numberString)")
print("number.floatValue: \(number.floatValue) //expected = \(numberString)")

print("** number and numberString converted into NSDecimalNumber different ways **")
let stringDecimalNumber: NSDecimalNumber = NSDecimalNumber(string: numberString)
let decimalDecimalNumber: NSDecimalNumber = NSDecimalNumber(decimal: number.decimalValue)
let doubleDecimalNumber: NSDecimalNumber = NSDecimalNumber(double: number.doubleValue)
let floatDecimalNumber: NSDecimalNumber = NSDecimalNumber(float: number.floatValue)

print("NSDecimalNumber(string: numberString): \(stringDecimalNumber) //expected = \(numberString)")
print("NSDecimalNumber(decimal: number.decimalValue): \(decimalDecimalNumber) //expected = \(numberString)")
print("NSDecimalNumber(double: number.doubleValue): \(doubleDecimalNumber) //expected = \(numberString)")
print("NSDecimalNumber(float: number.floatValue): \(floatDecimalNumber) //expected = \(numberString)")


print("** Add one to each NSDecimalNumber **")
print("stringDecimalNumber+1: \(NSDecimalNumber.one().decimalNumberByAdding(stringDecimalNumber)) // expected = \(numberString)+1")

print("decimalDecimalNumber+1: \(NSDecimalNumber.one().decimalNumberByAdding(decimalDecimalNumber)) // expected = \(numberString)+1")
print("doubleDecimalNumber+1: \(NSDecimalNumber.one().decimalNumberByAdding(doubleDecimalNumber)) // expected = \(numberString)+1")
print("floatDecimalNumber+1: \(NSDecimalNumber.one().decimalNumberByAdding(floatDecimalNumber)) // expected = \(numberString)+1")

print("** Formatted NSNumber and NSDecimalNumbers **")
print("number formatted: \(numberFormatter.stringFromNumber(number)!)")
print("stringDecimalNumber formatted: \(numberFormatter.stringFromNumber(stringDecimalNumber)!)")
print("decimalDecimalNumber formatted: \(numberFormatter.stringFromNumber(decimalDecimalNumber)!)")
print("doubleDecimalNumber formatted: \(numberFormatter.stringFromNumber(doubleDecimalNumber)!)")
print("floatDecimalNumber formatted: \(numberFormatter.stringFromNumber(floatDecimalNumber)!)")

我还没有在网上看到过这方面的任何内容,所以我想相信是我的错。那说我的游乐场代码很简单,所以我看不出我的错误。

0 个答案:

没有答案