gpt4 book ai didi

ios - 如何在不丢失精度的情况下从 String 解析 Decimal?

转载 作者:可可西里 更新时间:2023-11-01 00:54:09 24 4
gpt4 key购买 nike

我在我的应用程序中处理金额,因此精度显然非常重要,Decimal/NSDecimal 数字应该是快速处理金钱的方式。我想在保持精度的同时在 Decimal 和 String 之间进行转换。 (解析 API 响应,存储到 DB ...)

这是我目前的解决方案:

private let dotLocaleDictionary = [NSLocale.Key.decimalSeparator: "."]

func apiStringToDecimal(_ string: String) -> Decimal? {
let number = NSDecimalNumber(string: string, locale: dotLocaleDictionary) as Decimal
return number.isNaN ? nil : number
}

func decimalToApiString(_ decimal: Decimal) -> String {
return (decimal as NSDecimalNumber).description(withLocale: dotLocaleDictionary)
}

语言环境字典负责小数点分隔符,我希望字符串初始值设定项是精确的。但是在 Playground 上玩耍时,我注意到在输入一定长度的字符串后,结果数字会被截断。

我还尝试用数字格式化程序解析字符串,但结果更糟。

我的 Playground 代码:

let small = "1.135160000500009000100020003000400050061111"
let big = "1234567890123456789000100020003000400061111"
let medium = "123456789123456789.0001000200030004000511111"
let negative = "-123456789123456789.0001000200030004000511111"
let numericStrings = [small, big, medium, negative]

numericStrings.forEach {
print($0)
guard let decimal = apiStringToDecimal($0) else {
print("Failed to parse decimal from: \($0)")
print("--------------------")
return
}

print(decimal)
let string = decimalToApiString(decimal)
print($0 == string ? "match" : "mismatch")

print("--------------------")
}

let max = Decimal.greatestFiniteMagnitude
print("MAX decimal: \(max)")
print((max as NSDecimalNumber).description(withLocale: dotLocaleDictionary))
print(decimalToApiString(max))

它产生的输出:

1.135160000500009000100020003000400050061111
1.13516000050000900010002000300040005006
mismatch
--------------------
1234567890123456789000100020003000400061111
1234567890123456789000100020003000400060000
mismatch
--------------------
123456789123456789.0001000200030004000511111
123456789123456789.000100020003000400051
mismatch
--------------------
-123456789123456789.0001000200030004000511111
-123456789123456789.000100020003000400051
mismatch
--------------------
MAX decimal: 3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

从十进制转换为字符串似乎工作正常,将字符串转换为十进制似乎是个问题。由于我的数字小于最大十进制数,因此我认为我的测试数字不会太大。我很确定我已经排除了打印问题,并且我已经在实际设备上运行了代码,所以这不是 Playground 问题。

我做错了什么吗?有没有更好的方法在 swift 中实现 Decimal 和 String 之间的转换?

还是字符串太长了? (我还没有找到任何关于为什么这不起作用的文档/讨论)

最佳答案

来自 NSDecimalNumber

NSDecimalNumber, an immutable subclass of NSNumber, provides an object-oriented wrapper for doing base-10 arithmetic. An instance can represent any number that can be expressed as mantissa x 10^exponent where mantissa is a decimal integer up to 38 digits long, and exponent is an integer from –128 through 127.

(强调我的)

虽然 NSDecimalNumber 提供了高精度的十进制运算,但精度是有限制的。

您可能需要一个自定义库,例如 BigNum .

关于ios - 如何在不丢失精度的情况下从 String 解析 Decimal?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55844064/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com