You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Arduino从JsonDocument提取IPstack经纬度后float打印仅2位小数 如何输出全量小数位

问题根因定位

打印结果仅输出2位小数的问题和JsonDocument的数值提取逻辑无关,是两个平台固有机制共同导致的:

  • Arduino 串口打印API的默认规则:调用Serial.println()传入浮点变量但不指定第二参数时,固定仅输出2位小数,不会自动匹配变量的实际精度
  • 32位单精度float的本身属性:通用Arduino场景下的float是32位单精度浮点,仅能保证6-7位有效数字的精度,和接口返回的14位小数精度存在天然差值

解决方案

1. 手动指定串口打印的小数位数

Serial.println()支持通过第二个入参自定义输出的小数精度,直接修改原打印代码即可触发全精度输出:

// 原默认2位小数的打印代码
// Serial.println(latitudine);
// Serial.println(longitudine);

// 匹配float最大有效精度,输出7位小数
Serial.println(latitudine, 7);
Serial.println(longitudine, 7);

注意:不要强行把小数位数设为14来对齐接口返回值,32位float的有效精度上限就在7位左右,超出范围打印的尾数是无实际意义的随机值,和原始经纬度值偏差会很大。

2. 如需匹配接口返回的全量精度,替换存储类型

如果后续需要用经纬度做高精度计算,可以将存储类型从float改为64位双精度double,再指定对应小数位打印即可:

// 原float存储逻辑
// float latitudine  = doc["latitude"];
// float longitudine = doc["longitude"];

// 替换为double存储
double latitudine  = doc["latitude"];
double longitudine = doc["longitude"];

// 输出14位小数,对齐接口返回的原始精度
Serial.println(latitudine, 14);
Serial.println(longitudine, 14);

平台差异提醒:

  • ESP32/ESP8266 平台上的double为标准64位双精度,可完整承载14位小数的数值精度
  • AVR架构的传统Arduino(Uno、Nano等)上,double与float完全等价为32位单精度,无法提升精度;这种场景下如需保留全量原始数值,建议直接将JSON节点的内容以字符串形式读取存储。

可顺手优化的代码健壮性

当前代码未做反序列化错误判断,遇到接口返回非标准JSON时,会直接从空的JsonDocument中取到0值,可补充错误判断逻辑:

DeserializationError error = deserializeJson(doc, payload);
if (error) {
  Serial.print("JSON解析异常: ");
  Serial.println(error.c_str());
  return;
}

内容的提问来源于stack exchange,提问作者EdwardRadical

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.25 17:54:05