NSDecimalNumber 到 UInt64 的转换问题
NSDecimalNumber to UInt64 conversion issue
我已经实现了以下功能:
func number(for cof: UInt8, limit: UInt64) -> UInt64 {
let decimalResult = (1 + Decimal(cof)/255) * Decimal(limit) / 1000
return NSDecimalNumber(decimal: decimalResult).uint64Value
}
使用此函数后 0 cof
:
number(for: 0, gasLimit: 21000) // Result is 21
但是当我用不同的 cof
值调用函数时。
number(for: 128, gasLimit: 21000) // Result is 0
为 128 cof
值进行调试。
我发现
let decimalResult = (1 + Decimal(gasPriceCoef)/255) * Decimal(gasLimit) / 1000 // Result is 31.5411764705882352941176470588235294116
问题是,当我将 Decimal 值转换为 UInt64 时,我收到 0
这是因为 Decimal 值不是整数,& unint64Value 无法使用它。你总是可以只使用原语 -
let result = (1 + Double(cof) / 255) * Double(limit) / 1000
return UInt64(result)
这个 returns 操场上的正确结果 (31)
uint64Value
是 NSNumber
的 属性,应用于 NSDecimalNumber
.
时没有详细记录
但据我测试,当尾数部分超出UInt64
的范围时,它returns 0
。例如31.5411764705882352941176470588235294116
在NSDecimalNumber
中表示为315411764705882352941176470588235294116×10^(-38),而315411764705882352941176470588235294116
大于UInt64.max
。 (*1)
为避免这种行为 (*2),您可以在将十进制值转换为 UInt64
.
之前对其进行四舍五入
func number(for cof: UInt8, limit: UInt64) -> UInt64 {
var decimalResult = (1 + Decimal(cof)/255) * Decimal(limit) / 1000
var roundedResult = Decimal()
NSDecimalRound(&roundedResult, &decimalResult, 0, NSDecimalNumber.RoundingMode.plain)
return NSDecimalNumber(decimal: roundedResult).uint64Value
}
print(number(for: 128, limit: 21000)) //->32
(*1) 实际行为似乎有点复杂,请参阅上面 Martin R 评论中的较短的示例。
(*2) 一旦标记为已解决,此行为绝对是一个错误。另见上面 Martin R 的另一条评论。
我已经实现了以下功能:
func number(for cof: UInt8, limit: UInt64) -> UInt64 {
let decimalResult = (1 + Decimal(cof)/255) * Decimal(limit) / 1000
return NSDecimalNumber(decimal: decimalResult).uint64Value
}
使用此函数后 0 cof
:
number(for: 0, gasLimit: 21000) // Result is 21
但是当我用不同的 cof
值调用函数时。
number(for: 128, gasLimit: 21000) // Result is 0
为 128 cof
值进行调试。
我发现
let decimalResult = (1 + Decimal(gasPriceCoef)/255) * Decimal(gasLimit) / 1000 // Result is 31.5411764705882352941176470588235294116
问题是,当我将 Decimal 值转换为 UInt64 时,我收到 0
这是因为 Decimal 值不是整数,& unint64Value 无法使用它。你总是可以只使用原语 -
let result = (1 + Double(cof) / 255) * Double(limit) / 1000
return UInt64(result)
这个 returns 操场上的正确结果 (31)
uint64Value
是 NSNumber
的 属性,应用于 NSDecimalNumber
.
但据我测试,当尾数部分超出UInt64
的范围时,它returns 0
。例如31.5411764705882352941176470588235294116
在NSDecimalNumber
中表示为315411764705882352941176470588235294116×10^(-38),而315411764705882352941176470588235294116
大于UInt64.max
。 (*1)
为避免这种行为 (*2),您可以在将十进制值转换为 UInt64
.
func number(for cof: UInt8, limit: UInt64) -> UInt64 {
var decimalResult = (1 + Decimal(cof)/255) * Decimal(limit) / 1000
var roundedResult = Decimal()
NSDecimalRound(&roundedResult, &decimalResult, 0, NSDecimalNumber.RoundingMode.plain)
return NSDecimalNumber(decimal: roundedResult).uint64Value
}
print(number(for: 128, limit: 21000)) //->32
(*1) 实际行为似乎有点复杂,请参阅上面 Martin R 评论中的较短的示例。
(*2) 一旦标记为已解决,此行为绝对是一个错误。另见上面 Martin R 的另一条评论。