十进制数精确性错误是啥异常?
Posted
技术标签:
【中文标题】十进制数精确性错误是啥异常?【英文标题】:what kind exception is a decimal number exactness error?十进制数精确性错误是什么异常? 【发布时间】:2020-12-26 07:32:00 【问题描述】:在NSExceptionName阅读有关swift程序异常的信息,关于decimalNumberExactnessException的解释让我很困惑。什么是十进制数精确性错误,什么样的代码会得到一个decimalNumberExactnessException?
【问题讨论】:
对答案有任何反馈吗?如果您需要更多信息,请告诉我! 【参考方案1】:NSDecimalNumber
的精度为 38 位十进制数字。这是很大的,但不是无限的。例如,总和
let d1 = NSDecimalNumber(string: "12345678901234567890123456789")
let d2 = NSDecimalNumber(string: "0.000000000000000000123456789")
不能表示为NSDecimalNumber
。
默认行为是忽略精度损失并返回最接近的可表示数字:
let d1 = NSDecimalNumber(string: "12345678901234567890123456789")
let d2 = NSDecimalNumber(string: "0.000000000000000000123456789")
let d = d1.adding(d2)
print(d) // 12345678901234567890123456789
但是,可以更改默认行为,这是一个简单的示例:
let handler = NSDecimalNumberHandler(roundingMode: .plain, scale: 0,
raiseOnExactness: true, raiseOnOverflow: true,
raiseOnUnderflow: true, raiseOnDivideByZero: true)
NSDecimalNumber.defaultBehavior = handler
let d1 = NSDecimalNumber(string: "12345678901234567890123456789")
let d2 = NSDecimalNumber(string: "0.000000000000000000123456789")
let d = d1.adding(d2)
// Terminating app due to uncaught exception 'NSDecimalNumberExactnessException',
// reason: 'NSDecimalNumber exactness exception'
NSException
中抛出的异常可以在 Objective-C 中使用@try/@catch
捕获(但请参阅Objective-C Exceptions 了解一些警告)。 NSException
不能在 Swift 中被捕获。
在 Swift 中,如果您需要检查结果是否有可能的精度损失,您可以改用 NSDecimalAdd
:
var d1 = Decimal(string: "12345678901234567890123456789")!
var d2 = Decimal(string: "0.000000000000000000123456789")!
var r = Decimal()
let err = NSDecimalAdd(&r, &d1, &d2, .plain) // NSDecimalNumber.CalculationError
print(err == .lossOfPrecision) // true
【讨论】:
以上是关于十进制数精确性错误是啥异常?的主要内容,如果未能解决你的问题,请参考以下文章
完美解决Non-terminating decimal expansion; no exact representable decimal result.异常