Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios JSONObjectWithData解析时小数位数错误_Ios_Objective C_Json - Fatal编程技术网

Ios JSONObjectWithData解析时小数位数错误

Ios JSONObjectWithData解析时小数位数错误,ios,objective-c,json,Ios,Objective C,Json,在我的一个api中,我得到了下面的响应表单服务器(如果将数据转换为字符串) 但是当我用同样的方法 [NSJSONSerialization JSONObjectWithData:data options:self.readingOptions error:&serializationError]; 它的回归 { Total = "68.59999999999999"; "delivery_date" = "2016-03-25"; "delivery_time" = "7:30PM-1

在我的一个api中,我得到了下面的响应表单服务器(如果将数据转换为字符串)

但是当我用同样的方法

[NSJSONSerialization JSONObjectWithData:data options:self.readingOptions error:&serializationError];
它的回归

{
Total = "68.59999999999999";
"delivery_date" = "2016-03-25";
"delivery_time" = "7:30PM-10:00PM";
"order_id" = 102232;
success = 1;
}

由于“总计”字段中小数点后有多个位置,因此在计算中会产生问题


我认为JSON序列化方法在内部转换它,但不知道如何解决这个问题,因为您使用的是浮点算法。你所看到的是完全正常的。如果你只分配了68.6,同样的事情也会发生

你如何解决这个问题?通过学习浮点运算。但你实际上看到了什么问题?你只是因为看到大量的“9”而惊慌失措,还是真的有问题

究竟是什么让您认为将数据转换回JSON会产生服务器误解的东西?你试过了吗?你是在担心理论上的可能性,还是你有问题的实际证据?显然,服务器存储了四舍五入到一个小数点的内容


我的意思是,你真的知道你担心的是NSLog语句的输出吗

@gnasher暗示了这个问题,但没有详细解释

计算机使用二进制浮点在内部表示浮点数

浮点数通常存储为浮点数或双精度浮点数。在大多数64位平台上,浮点存储在4字节中,双精度存储在8字节中

二进制浮点不能准确地表示许多十进制值。在内部,68.6以二进制表示,其值以十进制表示为68.5999999999。这是计算机在将值保存为浮点数时最接近68.6的数值

二进制浮点值(如浮点数和双精度浮点值)没有“小数位数”。该值被转换为十进制以供显示,或转换为字符串,并且在转换过程中始终存在舍入错误的可能性

以这段代码为例:

float aFloat = 68.6;
NSLog(@"aFloat = %f", aFloat);
这显示:

aFloat = 68.599998
但是,该代码:

NSLog(@"aFloat (1 decimal place)= %.1f", aFloat);
显示:

aFloat (1 decimal place)= 68.6
正在解析的JSON字符串中包含不带引号的数字。当您将JSON字符串转换为Cocoa对象时,“Total”的值将保存为NSNumber对象,可能在内部使用双精度类型

如果你需要计算你的“总”值,那么你需要它是一个数字

如果要避免十进制转换错误,请更改服务器代码,将值“Total”作为字符串(引号中)而不是数字值发送。然后,
JSONObjectWithData
函数将其作为字符串保存,
“68.6”

在这种情况下,JSON字符串如下所示:

{"success":true,"order_id":102232,"Total":"68.6","delivery_time":"7:30PM-10:00PM","delivery_date":"2016-03-25"}

您说“由于总计字段中小数点后有多个位置,所以在计算中会产生问题。”什么问题?在iOS端还是服务器端?

这解决了我的问题

NSNumberFormatter *fmt = [[NSNumberFormatter alloc] init];
[fmt setPositiveFormat:@"0.##"];
NSLog(@"%@", [fmt stringFromNumber:dataDict[@"Total"]]);

此日志的输出为68.6

Swift在解析时遇到相同问题,后端团队正在发送decimal。把它藏起来让它漂浮

let value = Float(48.9999999999)
print(value) // 49.0

let value = Float(48.9799999999)
print(value) // 48.98

您要传递哪一个读取选项?有时在键入值时,浮点值不够精确。它不会伤害你的程序,直到你需要确切的值。当你轮换时,你会在这里得到你想要的。我不能轮换,因为我需要将它发送回服务器,并在那里进行验证,因此单一精度可能会扭曲功能请通读,这是一个完全正确的行为。在向用户显示数字时,只需使用
NSNumberFormatter
。请参阅此问题是将.6转换为.599999999时失败,因为现在我拥有的值是.59999,而不是.599999。6@iOSRocks在这种情况下,问题出在服务器上。有一些方法可以解决这个问题,例如使用
NSDecimalNumber
保存数字,使用自定义的JSON解析器和编码器,但是修复服务器要容易得多。同样的事情在Android上也可以正常工作,所以我们无法更改服务器端代码。实际上,在iOS上,JSON解析器将所有数字转换为
NSNumber
(具有双精度)即使是我们希望保留为
NSDecimalNumber
的解析器(例如
SBJson
)我也有同样的问题。有一次我想正确解析,我不得不用一个解析器来修复这个行为。听起来苹果需要增强NSJSONSerialization来添加一个选项,为JSON字符串中包含的十进制值创建NSDecimalNumber对象。你发布了你的自定义
JSON
parser吗?@Duncac是的,那会d是正确的解决方案。与
NSNumberFormatter
相同,它也将
NSDecimalNumber
转换为
double
(也只能由专有格式化程序修复)。不幸的是,我更新的解析器无法发布(公司代码)。它是
SBJson
的第一个版本之一的分支,修复实际上非常简单。(顺便说一句,javascript解析器也有同样的问题,也转换为双精度)。我不确定这是否是一个“大问题”在某种意义上说,99.99%的NSJSONSerialization的消费者想要普通的C原语数,而其他人不一定会满足于
NSDecimalNumber
NSDecimalNumber
是一个64位浮点量,与
double
完全相同,它恰好有一个基数10指数而不是基数2。如果要“正确解析”您需要一个可变大小的数字存储容器。我可以在JSON中编码无限多的数字,这些数字不能存储为
NSDecimalNumber
@Tommy,JSON将数字作为十进制数字字符串发送。在JSON和本机数据格式之间来回转换会强制在二进制和十进制表示之间进行转换数字,具有潜在的fo
let value = Float(48.9999999999)
print(value) // 49.0

let value = Float(48.9799999999)
print(value) // 48.98