如果NSDecimalNumber大于Uint64,如何将NSDecimalNumber转换为字节数组?

时间:2018-12-06 23:38:40

标签: arrays swift nsdecimalnumber

我想将NSDecimalNumber转换为字节数组。另外,我不想将任何库用于BigInt,BInt等。

我尝试了这个:

$(".grid-item").each(function(i) {
    setTimeout(function(){
        // add you ajax code here
    },500 * i);
});

如果该数字不大于Uint64,则效果很好。但是,如果是的话,我们该如何转换呢?

2 个答案:

答案 0 :(得分:2)

问题显然是使用uint64Value,显然不能表示任何大于UInt64.max的值,而您的示例59,785,897,542,892,656,787,456大于该值。

如果要获取128位尾数的字节表示形式,可以使用_mantissaUInt16个单词的Decimal元组,并根据需要将它们转换为字节。例如

extension Decimal {
    var byteArray: [UInt8] {
        return [_mantissa.0,
                _mantissa.1,
                _mantissa.2,
                _mantissa.3,
                _mantissa.4,
                _mantissa.5,
                _mantissa.6,
                _mantissa.7]
            .flatMap { [UInt8($0 & 0xff), UInt8($0 >> 8)] }
    }
}

还有

if let foo = Decimal(string: "59785897542892656787456") {
    print(foo.byteArray)
}

返回:

  

[0,0,0,0,0,0,0,0,169,12,0,0,0,0,0,0]

诚然,这仅解决了问题,打破了uint64Value方法的64位限制,但仍然受限于NSDecimalNumber / Decimal固有的128位限制。要捕获大于128位的数字,您需要一个完全不同的表示形式。


NB:这也假设指数为0。但是,如果您有一些数字,例如4.2e101(4.2 * 10 101 ),指数将为100,尾数将仅为42,我敢打赌这可能不是您想要的字节数组。再说一遍,这是一个数字的示例,该数字太大了,无论如何不能表示为单个128位整数:

if let foo = Decimal(string: "4.2e101") {
    print(foo.byteArray)
    print(foo.exponent)
}

屈服:

  

[42,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
  100

答案 1 :(得分:0)

您传递的是value.uint64Value,而不是value。因此,该数字将被包裹为零,以使NSDecimal适应UInt64格式。

传递"18446744073709551616"(与UInt64.max +1相对应的字符串)等效于传递"0"。传递"18446744073709551617"(相当于UInt64.max + 2的字符串)等效于传递"1"