十进制数精确性错误是啥异常?

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

【讨论】:

以上是关于十进制数精确性错误是啥异常?的主要内容,如果未能解决你的问题,请参考以下文章

16进制转汉字的原理是啥

计算具有相同汉明权重的二进制数的所有排列的最快算法是啥?

c语言16进制转换为10进制数的函数是啥?

modbus+rtu功能码是啥进制数

二进制计数器的模值是啥意思?呀

完美解决Non-terminating decimal expansion; no exact representable decimal result.异常