ios json 解析丢失精度

本文探讨了在iOS开发中使用NSJSONSerialization处理包含小数的JSON数据时遇到的精度误差问题,并提供了一种解决方案及替代方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当json字典中含有一位及以上小数位时,在使用NSJSONSerialization方法先转为NSData再解析为字符串时有时会出现数据误差,代码如下:

NSString *jsonStr = @"{"number":81.6}";

    

    NSData *jsonData_ = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];

    

    NSError *jsonParsingError_ = nil;

    

   NSDictionary *dic=[NSJSONSerializationJSONObjectWithData:jsonData_ options:NSJSONReadingAllowFragments error:&jsonParsingError_];

    

      NSString *value=dic[@"number"];

    

    NSLog(@"value:%@ ----", value);

 
打印结果:2016-01-28 09:43:40.827 test[775:19343] value:81.59999999999999 ----
 
猜想可能是数据转换时精度的问题,因此修改了一下最后解析时的代码,替换了一下value的解析方法如下:

NSString *value=[NSString stringWithFormat:@"%f",[dic[@"number"] doubleValue]];

 

打印结果: 2016-01-28 09:50:57.627 test[958:23205] value:81.600000 ----

至少数据显示是正常了,当然还可以叫后端开发的兄弟全部返回字符串,也是可以解决这个问题的

<think>好的,用户的问题是在Unity中解析JSON字符串并提取position字段的值。我需要结合之前的对话和用户提供的引用来给出合适的解决方案。首先,回顾之前的回答,用户已经知道两种方法:使用Unity内置的JsonUtility和第三方库SimpleJSON。现在用户再次提问,可能希望更详细的步骤或者不同的方法。 查看用户提供的引用,引用[1]提到使用JObject.Parse,这应该是Newtonsoft的Json.NET库,但用户之前的回答提到Json.NET可能有iOS兼容性问题。引用[2]展示了JsonUtility的使用和调试技巧,引用[3]和[4]涉及数据序列化和编辑器扩展,可能与当前问题关系不大。用户现在的问题核心是提取position字段的值,可能需要考虑不同情况,比如是否嵌套结构,或者是否需要动态解析。根据之前的回答,用户可能更倾向于官方推荐的方法,所以优先推荐JsonUtility,但也要提到其他方法如Json.NET和SimpleJSON,并指出各自的优缺点。需要检查用户提供的JSON字符串是否有错误,比如原问题中的字符串末尾有“STAR_GAME”后面是中文引号,可能导致解析错误。需要提醒用户确保JSON格式正确,否则解析会失败。 另外,用户可能在实际操作中遇到字段不匹配或者类型转换的问题,需要强调类结构必须与JSON键名一致,并且处理字符串到数值的转换,比如使用float.Parse。 还需要考虑错误处理,比如空引用检查和类型转换检查,如使用TryParse来避免异常。 最后,生成相关问题时,要围绕JSON解析的其他常见问题,比如处理数组、嵌套结构、不同数据类型转换等。</think>### Unity解析JSON字符串提取position字段的完整方案 #### 一、使用JsonUtility原生方案(推荐) 1. **定义数据结构** 创建与JSON结构严格对应的C#类,注意字段命名必须**完全一致**: ```csharp [System.Serializable] public class Position { public string x; public string y; public string z; } [System.Serializable] public class GameData { public string data; public Position position; // 目标嵌套结构 } ``` 2. **反序列化操作** 通过`JsonUtility.FromJson`方法转换并提取值: ```csharp string json = "{\"data\":\"walk\",\"position\":{\"x\":\"0\",\"y\":\"0.025\",\"z\":\"-1.4\"}}"; GameData parsedData = JsonUtility.FromJson<GameData>(json); // 提取position对象 Vector3 pos = new Vector3( float.Parse(parsedData.position.x), float.Parse(parsedData.position.y), float.Parse(parsedData.position.z) ); Debug.Log($"坐标:{pos}"); // 输出:(0.0, 0.0, -1.4) ``` 3. **调试技巧** 使用格式化输出验证数据结构匹配性[^2]: ```csharp JsonDebugger.LogJson(parsedData, "解析结果"); ``` #### 二、使用Json.NET方案(第三方库) 1. **动态解析模式** 当JSON结构动态变化时,使用Newtonsoft.Json库: ```csharp using Newtonsoft.Json.Linq; string json = "{\"position\":{\"x\":1.5}}"; JObject obj = JObject.Parse(json); JToken positionToken = obj["position"]; float x = (float)positionToken["x"]; // 直接转换数值类型 ``` 2. **类型安全处理** 通过`TryGetValue`避免空引用: ```csharp if (obj.TryGetValue("position", out JToken posToken)) { if (posToken["x"] != null) { float x = posToken.Value<float>("x"); } } ``` #### 三、错误处理关键点 1. **格式验证** 先检查原始JSON有效性: ```csharp if (string.IsNullOrEmpty(json) || !json.Contains("position")) { throw new ArgumentException("无效JSON"); } ``` 2. **类型转换保护** 使用安全转换方法: ```csharp if (float.TryParse(parsedData.position.x, out float xVal)) { // 安全使用xVal } else { Debug.LogError($"非法数值:{parsedData.position.x}"); } ``` #### 四、性能优化建议 | 操作 | 优化方法 | 作用 | |--------------------|---------------------------------|------------------------| | 频繁解析 | 使用对象池复用解析实例[^3] | 减少GC压力 | | 大文件处理 | 分块解析+协程加载 | 避免主线程卡顿 | | 网络数据传输 | 压缩JSON字符串(如GZip)[^4] | 减少传输量 | ### 常见问题排查 - **字段缺失**:使用`[System.Serializable]`时确保所有层级字段都被定义 - **数值精度丢失**:使用`double`类型代替`float`处理高精度需求 - **编码问题**:确保JSON字符串使用UTF-8编码[^4]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值