JSON中非常大的ID,如何在不丢失精度的情况下获取它

Posted

技术标签:

【中文标题】JSON中非常大的ID,如何在不丢失精度的情况下获取它【英文标题】:Very big ID in JSON, how to obtain it without losing precision 【发布时间】:2014-12-09 21:06:43 【问题描述】:

我在 JSON 文件中有 ID,其中一些非常大,但它们适合 unsigned long long int 的范围。

"id":9223372036854775807,

如何使用 NSDictionary 的 objectForKey:idKey 从 JSON 中获取这么大的数字? 我可以使用 NSDecimalNumber 吗?其中一些 ID 适合常规整数。

【问题讨论】:

见***.com/questions/20198040/… 为什么不把id当作字符串呢?无需将其转换为数字,因为您不会对 id 进行任何数学运算。 我稍后在代码中需要这个 id。 好的,这与使用字符串作为 id 有什么关系? 仅供比较。我会尝试字符串并让你知道。 【参考方案1】:

棘手。 Apple 的 JSON 代码将 10^18 以上的整数转换为 NSDecimalNumber,将较小的整数转换为包含 64 位整数值的普通 NSNumber。现在你可能希望 unsignedLongLongValue 会给你一个 64 位的值,但它不会用于 NSDecimalNumber:NSDecimalNumber 首先被转换为双精度,结果为 unsigned long long,所以你失去了精度。

您可以将以下内容添加为 NSNumber 的扩展。这有点棘手,因为如果你得到一个非常接近 2^64 的值,将其转换为双精度可能会舍入为 2^64,而不能转换为 64 位。所以我们需要先除以 10 以确保结果不会太大。

- (uint64_t)unsigned64bitValue

    if ([self isKindOfClass:[NSDecimalNumber class]])
    
        NSDecimalNumber* asDecimal = (NSDecimalNumber *) self;
        uint64_t tmp = (uint64_t) (asDecimal.doubleValue / 10.0);

        NSDecimalNumber* tmp1 = [[NSDecimalNumber alloc] initWithUnsignedLongLong:tmp];
        NSDecimalNumber* tmp2 = [tmp1 decimalNumberByMultiplyingByPowerOf10: 1];
        NSDecimalNumber* remainder = [asDecimal decimalNumberBySubtracting:tmp2];

        return (tmp * 10) + remainder.unsignedLongLongValue;
    
    else
    
        return self.unsignedLongLongValue;
    

【讨论】:

但是我可以使用来自 NSDecimalNumber 的比较,它应该可以工作吗?【参考方案2】:

或者处理原始的 JSON 字符串,寻找 '"id" = number; '。通常包含空格,您可以找到数字,然后用引用的数字覆盖它。您可以将数据放入可变数据对象并获取指向它的 char 指针,以进行覆盖。

[使用 iPhone 输入,所以有点简洁]

【讨论】:

以上是关于JSON中非常大的ID,如何在不丢失精度的情况下获取它的主要内容,如果未能解决你的问题,请参考以下文章

Kivy PyInstaller 在 Linux 中非常大的包大小

Powershell 中非常大的 XML 文件

C/C++ 中非常大的静态数组的算术运算

R中非常大的矩阵计算有效

R中非常大的稀疏矩阵的列重新缩放

R程序中非常大的矩阵的svd