NSNumber 值在 JSON 对象转换为数据时发生变化,然后该数据再次转换回 JSON 对象

Posted

技术标签:

【中文标题】NSNumber 值在 JSON 对象转换为数据时发生变化,然后该数据再次转换回 JSON 对象【英文标题】:NSNumber value changing when JSON object is converted to data and then that data is again converted back to JSON object 【发布时间】:2018-05-08 07:20:06 【问题描述】:

我正在使用字典创建NSData 对象,如下所示,

字典


    channelId = 201;
    lang = EN;
    reqRefNo = vZRIzNd;
    storeInfo =     
        clientInfo =         
            deviceId = XXXXXXXXA67F488B836D19D80EC4FD8D;
        ;
        loginLogId = XXXXXXXX5CAD4A0DA06BE2F055929856;
        qrCodeInfo =         
            itemDesc = "";
            itemName = hahsj;
            price = 106;
        ;
        userInfo =         
            storeId = 3252;
        ;
    ;

价格 = 106

NSData *data = [NSJSONSerialization dataWithJSONObject:paramDict options:kNilOptions error:nil];

现在我再次将其转换回 JSON 对象,如下所示,

NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data
                                                         options:kNilOptions
                                                       error:&error];

但是这次我弄错了价格。

转换后的字典


    channelId = 201;
    lang = EN;
    reqRefNo = vZRIzNd;
    storeInfo =     
        clientInfo =         
            deviceId = XXXXXXXXA67F488B836D19D80EC4FD8D;
        ;
        loginLogId = XXXXXXXX5CAD4A0DA06BE2F055929856;
        qrCodeInfo =         
            itemDesc = "";
            itemName = hahsj;
            price = "105.9999923706055";
        ;
        userInfo =         
            storeId = 3252;
        ;
    ;

价格 = "105.9999923706055"

生成NSNumber的代码,

//_amountTF.text = "S$1.06";
NSString *amount = [_amountTF.text stringByReplacingOccurrencesOfString:@"S$" withString:@""];
float amt = [amount floatValue];
amt *=100;
NSNumber *num = [NSNumber numberWithFloat:amt];

谁能解释一下这背后的原因?谢谢。

【问题讨论】:

你能添加你用来创建字典的代码吗? 两种数据类型是否相同?价格 = 106;和价格=“105.9999923706055”; ? @trungduc 使用 setObject forkey 方法创建的普通 NSMutableDictionary。 @PrashantTukadiya 在将其 NSNumber 转换为 NSData 之前,我不知道转换后会发生什么。 这是一个浮点精度问题。使用doubleCGFloat 而不是float 【参考方案1】:

这是一个浮点精度问题。使用double 而不是float

您的数字以二进制格式存储,无法准确表示所有十进制值,因此某些值会“四舍五入”到最接近的二进制值。打印数字时,它会先将您的浮点数转换为双精度,然后再打印。转换为 double 将采用您的四舍五入二进制表示并以更高的精度存储,使其具有高精度和低精度内容。打印这将显示使用浮点精度时得到的近似值。

NSString *amount = [_amountTF.text stringByReplacingOccurrencesOfString:@"S$" withString:@""];
double amt = [amount doubleValue];
amt *=100;
NSNumber *num = [NSNumber numberWithDouble:amt];

阅读更多:'float' vs. 'double' precision

【讨论】:

【参考方案2】:

同时。创建字典添加价格值:

price = [NSString stringWithFormat:@"106"]; 或者, int priceValue = 106; price = [NSString stringWithFormat:@"%d",priceValue];

现在转换字典。将是您需要的任何东西。

【讨论】:

以上是关于NSNumber 值在 JSON 对象转换为数据时发生变化,然后该数据再次转换回 JSON 对象的主要内容,如果未能解决你的问题,请参考以下文章

使用 NSNumberFormatter 和 RestKit 将 NSCFNumber 转换为 NSNumber 时出错

将 JSON ARRAY 转换为 NSNumber 数组

Restkit 从 NSNumber 序列化布尔值

React Native - nsnumber类型的json值'0'无法转换为nsstring

nsnumber 类型的 json 值“2”无法转换为 nsstring

从 plist/dictionary 转换为 NSNumber 时出错