double.Parse在不同计算机返回值异常的排查及数据修正需求
问题根源
出现异常值的核心原因是区域文化设置差异导致的数值解析/格式化行为不一致:
- 你的电脑使用点(
.)作为小数点分隔符,double.Parse默认遵循当前区域规则,能正确识别GPS数据中的小数点; - 同事的电脑使用逗号(
,)作为小数点分隔符,double.Parse会将GPS字符串中的点(.)视为无效分隔符并忽略,导致解析出的数值被错误放大(例如"51.22113"会被解析为5122113而非51.22113),最终计算出完全错误的经纬度。
代码修复方案
必须强制使用**不变文化(InvariantCulture)**解析GPS数据(因为GPS协议的数值格式固定用点作为小数点,与系统区域无关),同时可按需统一显示格式避免区域差异。修改后的代码如下:
using System.Globalization; double latitude, longitude; if (gps_response_valid && gps_response.Contains("$GNGGA") && gps_response.Contains('M')) { int ptr = gps_response.IndexOf("$GNGGA"); string lat = gps_response.Substring(ptr + 17, 10); // 解析时指定InvariantCulture,确保点被识别为小数点 var latDegrees = double.Parse(lat.Substring(0, 2), CultureInfo.InvariantCulture); var latMinutes = double.Parse(lat.Substring(2, 8), CultureInfo.InvariantCulture); latitude = latDegrees + (latMinutes / 60); if (gps_response[ptr + 28] == 'S') latitude = -latitude; string lon = gps_response.Substring(ptr + 30, 11); var lonDegrees = double.Parse(lon.Substring(0, 3), CultureInfo.InvariantCulture); var lonMinutes = double.Parse(lon.Substring(3, 8), CultureInfo.InvariantCulture); longitude = lonDegrees + (lonMinutes / 60); // 显示时若需统一用点作为小数点,指定InvariantCulture;若要适配区域,可改用CurrentCulture label_lat_data.Text = latitude.ToString(CultureInfo.InvariantCulture); label_lon_data.Text = longitude.ToString(CultureInfo.InvariantCulture); }
关键修改点:
- 引入
System.Globalization命名空间; - 所有
double.Parse调用添加CultureInfo.InvariantCulture参数,强制按固定规则解析; - 可选:
ToString时指定InvariantCulture,保证显示的小数点格式统一。
异常数据修正方法
同事电脑上记录的异常值是错误解析导致的,可通过逆推逻辑修正:
以纬度异常值85420,86666666667为例:
- 提取原始GPS数据中的度数值(纬度前两位为
50,经度前三位为005即5); - 用异常值减去度数值:
85420.86666666667 - 50 = 85370.86666666667; - 乘以60得到错误解析的分钟数:
85370.86666666667 * 60 = 5122252; - 将该整数转为字符串,在第2位后插入小数点,得到正确的分钟字符串:
"51.22252"; - 重新计算正确纬度:
50 + (51.22252 / 60) ≈ 50.8537083333。
若能获取原始GPS串,直接用修复后的代码重新计算是最准确的方式;若无原始数据,可通过上述逻辑批量修正异常记录。
内容的提问来源于stack exchange,提问作者Tirdad the Whitehand
相关产品推荐
相关产品推荐

