我已经实现了以下功能:
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
答案 0 :(得分:3)
uint64Value
是NSNumber
的属性,并且应用于NSDecimalNumber
时没有充分的文档说明。
但是据我测试,当尾数部分超过UInt64
的范围时,它将返回0
。例如,31.5411764705882352941176470588235294116
表示为{{1}中的315411764705882352941176470588235294116×10 ^(-38),并且NSDecimalNumber
大于315411764705882352941176470588235294116
。 (* 1)
为避免此现象(* 2),您可以在将十进制值转换为UInt64.max
之前将其舍入。
UInt64
(* 1)实际行为似乎有点复杂,请参阅上面Martin R的评论中的 Shorter示例。
(* 2)一旦标记为已解决,此行为肯定是一个错误。另请参阅上面Martin R的另一条评论。
答案 1 :(得分:1)
这是因为Decimal值不是整数,&unint64Value不适用于该值。您始终可以只使用基元-
let result = (1 + Double(cof) / 255) * Double(limit) / 1000
return UInt64(result)
这会在操场上返回正确的结果(31)