NSDecimalNumber到UInt64的转换问题

时间:2018-09-20 16:56:51

标签: swift decimal nsdecimalnumber

我已经实现了以下功能:

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

2 个答案:

答案 0 :(得分:3)

uint64ValueNSNumber的属性,并且应用于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)