Arduino ESP8266 浮点数精度问题:保留指定位数、精度丢失

最近币市熊的一塌糊涂,闲来无事,正好在玩Arduino ESP8266相关硬件,成功晋身“电子垃圾佬”。那么就想用 ESP8266+一个LCD屏幕 自己做一个能够显示币行情的小玩意儿,解解闷。结果发现一个尴尬的问题,SHIB(屎币)的价格小数点后面五六个零,在反序列化json的时候,价格等行情类的对象应该反转成什么类型呢?简单处理直接用 u8g2.drawStr(x,y,str) 输出到屏幕,又只保留两位小数……
伴随着这种苦恼,就有了这篇……

一、我们先来看看Arduino官方的类型介绍

float
[Data Types]
Description
Datatype for floating-point numbers, a number that has a decimal point. Floating-point numbers are often used to approximate analog and continuous values because they have greater resolution than integers. Floating-point numbers can be as large as 3.4028235E+38 and as low as -3.4028235E+38. They are stored as 32 bits (4 bytes) of information.

Syntax
float var = val;

Parameters
var: variable name.
val: the value you assign to that variable.

Example Code
float myfloat;
float sensorCalbrate = 1.117;

int x;
int y;
float z;

x = 1;
y = x / 2; // y now contains 0, ints can’t hold fractions
z = (float)x / 2.0; // z now contains .5 (you have to use 2.0, not 2)
Notes and Warnings
If doing math with floats, you need to add a decimal point, otherwise it will be treated as an int. See the Floating point constants page for details.

The float data type has only 6-7 decimal digits of precision. That means the total number of digits, not the number to the right of the decimal point. Unlike other platforms, where you can get more precision by using a double (e.g. up to 15 digits), on the Arduino, double is the same size as float.

Floating point numbers are not exact, and may yield strange results when compared. For example 6.0 / 3.0 may not equal 2.0. You should instead check that the absolute value of the difference between the numbers is less than some small number.

Conversion from floating point to integer math results in truncation:

float x = 2.9; // A float type variable
int y = x; // 2
If, instead, you want to round off during the conversion process, you need to add 0.5:

float x = 2.9;
int y = x + 0.5; // 3
or use the round() function:

float x = 2.9;
int y = round(x); // 3
Floating point math is also much slower than integer math in performing calculations, so should be avoided if, for example, a loop has to run at top speed for a critical timing function. Programmers often go to some lengths to convert floating point calculations to integer math to increase speed.

点击这里查看原文介绍

看介绍,好像和我们熟悉的float也没啥区别。但是我着重标记强调的地方很关键:float类型的精度只有6-7位小数,这意味着总位数不仅仅包含小数点后面的,还包含整数部分。
这个好难理解!好羞涩!讲不出来大道理的时候,就用代码来验证吧。

有些同学可能就会说,为啥不用double?很好,这表示你和我一样,带着脑子在思考这件事儿。

其实float介绍里面已经说明了。我们到double类型的介绍看看:
在这里插入图片描述

二、如何保留float小数位?

我们将要用到String()构造函数。
在这里插入图片描述
点击这里查看原文详细介绍
我们可以看到,构造函数中可以指定float或double类型参数,然后指定保留小数位。

三、代码验证部分

void setup() {
   
  Serial.begin(9600);
  //串口打印:1 1
  Serial.print("1\t");Serial.println(String(1, 2));
  //串口打印:1.  1.00
  Serial.print("1.\t");Serial.println(String(1., 2));
  //串口打印:1.1 1.10
  Serial.print("1.1\t");Serial.println(String(1.1, 2));
  //串口打印:1.01  1.01
  Serial.print("1.01\t");Serial.println(String(1.01, 2));
  //串口打印:1.014 1.01
  Serial
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值