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

更新时间:2023-07-13 00:40:20 阅读: 评论:0

ArduinoESP8266浮点数精度问题:保留指定位数、精度丢失
最近币市熊的⼀塌糊涂,闲来⽆事,正好在玩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 ud to approximate analog and continuous values becau 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 nsorCalbrate = 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 u 2.0, not 2)
Notes and Warnings
If doing math with floats, you need to add a decimal point, otherwi 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 u 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 increa speed.
看介绍,好像和我们熟悉的float也没啥区别。但是我着重标记强调的地⽅很关键:float类型的精度只
有6-7位⼩数,这意味着总位数不仅仅包含⼩数点后⾯的,还包含整数部分。
这个好难理解!好羞涩!讲不出来⼤道理的时候,就⽤代码来验证吧。
有些同学可能就会说,为啥不⽤double?很好,这表⽰你和我⼀样,带着脑⼦在思考这件事⼉。
其实float介绍⾥⾯已经说明了。我们到double类型的介绍看看:
⼆、如何保留float⼩数位?
我们将要⽤到String()构造函数。
正手攻球我们可以看到,构造函数中可以指定float或double类型参数,然后指定保留⼩数位。
三、代码验证部分
void tup(){
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.print("1.014\t");Serial.println(String(1.014,2));
高中数学练习题//串⼝打印:1.015 1.01
Serial.print("1.015\t");Serial.println(String(1.015,2));
//串⼝打印:1.016 1.02
Serial.print("1.016\t");Serial.println(String(1.016,2));
//串⼝打印:1.019 1.02
Serial.print("1.019\t");Serial.println(String(1.019,2));
//串⼝打印:0.0000002342  0.0000002342
Serial.print("0.0000002342\t");Serial.println(String(0.0000002342,10));
float f1 =0.000000001;//9位⼩数
float f1 =0.000000001;//9位⼩数
float f2 =0.000000002;//9位⼩数
float f3 = f1 + f2;
//串⼝打印:0.000000001+0.000000002=0.0000000030
Serial.print("0.000000001+0.000000002=");Serial.println(String(f3,10));
float f11 =0.000000001;//9位⼩数
float f21 =0.0000000025;//10位⼩数
float f31 = f11 + f21;
//串⼝打印:0.000000001+0.0000000025=0.0000000035
Serial.print("0.000000001+0.0000000025=");Serial.println(String(f31,10));
Serial.println("");
float f12 =599999.123456781;
float f22 =1.0000000025;
float f32 = f12 + f22;
//串⼝打印:599999.123456781+1.0000000025=600000.1300000000
Serial.print("599999.123456781+1.0000000025=");Serial.println(String(f32,10));
Serial.println("");
float f18 =1234567.123456781;
float f28 =1.0000000025;
float f38 = f18 + f28;
//串⼝打印:1234567.123456781+1.0000000025=1234568.1000000000
冲厕所
全屏显示Serial.print("1234567.123456781+1.0000000025=");Serial.println(String(f38,10));
Serial.println("");
float f19 =1234567.123456781;
float f29 =1.0400000025;
float f39 = f19 + f29;
//串⼝打印:1234567.123456781+1.0400000025=
Serial.print("1234567.123456781+1.0400000025=");Serial.println(String(f39,10));
Serial.println("");
float f110 =1234567.12;
float f210 =1.07;
float f310 = f110 + f210;
/
/串⼝打印:1234567.12+1.05=1234568.3000
Serial.print("1234567.12+1.05=");Serial.println(String(f310,4));
Serial.println("");
float f13 =599999.2221;
float f23 =1.00025;
float f33 = f13 + f23;
//串⼝打印:599999.2221+1.00025=600000.2500000000
Serial.print("599999.2221+1.00025=");Serial.println(String(f33,10));
//串⼝打印:599999.2221+1.00025=600000.2500
Serial.print("599999.2221+1.00025=");Serial.println(String(f33,4));
Serial.println("");
float f14 =1234.1234;氯化铵和氢氧化钙
float f24 =1.00015;
float f34 = f14 + f24;
//串⼝打印:1234.1234+1.00015=1235.1235000000
Serial.print("1234.1234+1.00015=");Serial.println(String(f34,10));
//串⼝打印:1234.1234+1.00015=1235.1235
Serial.print("1234.1234+1.00015=");Serial.println(String(f34,4));
Serial.println("");
float f15 =1234.1234;
float f25 =1.00018;
float f35 = f15 + f25;
/
/串⼝打印:1234.1234+1.00018=1235.1235000000
Serial.print("1234.1234+1.00018=");Serial.println(String(f35,10));
Serial.print("1234.1234+1.00018=");Serial.println(String(f35,10)); //串⼝打印:1234.1234+1.00018=1235.1235
Serial.print("1234.1234+1.00018=");Serial.println(String(f35,4));
Serial.println("");
float f16 =14.1234;
float f26 =1.000068;
float f36 = f16 + f26;
//串⼝打印:14.1234+1.000068=15.1234670000
Serial.print("14.1234+1.000068=");Serial.println(String(f36,10)); //串⼝打印:14.1234+1.000068=15.1235
Serial.print("14.1234+1.000068=");Serial.println(String(f36,4)); //串⼝打印:14.1234+1.000068=bright怎么读
Serial.print("14.1234+1.000068=");Serial.println(String(f36,5)); //串⼝打印:14.1234+1.000068=
Serial.print("14.1234+1.000068=");Serial.println(String(f36,6));
Serial.println("");
float f17 =143.1234;
float f27 =1.000068;
float f37 = f17 + f27;
//串⼝打印:143.1234+1.000068=144.1234600000
Serial.print("143.1234+1.000068=");Serial.println(String(f37,10)); //串⼝打印:14.1234+1.000068=144.1235
Serial.print("143.1234+1.000068=");Serial.println(String(f37,4)); //串⼝打印:14.1234+1.000068=144.12346
生源地贷款还款Serial.print("143.1234+1.000068=");Serial.println(String(f37,5)); //串⼝打印:14.1234+1.000068=144.123460
Serial.print("143.1234+1.000068=");Serial.println(String(f37,6)); }
void loop(){
// put your main code here, to run repeatedly:
}

本文发布于:2023-07-13 00:40:20,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1093413.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:类型   保留   指定   精度   位数
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图