ESP8266 "ovf" 做小双数时
ESP8266 "ovf" when doing small double maths
我正在使用基于 ESP8266 wifi 芯片和 Arduino C 框架的 Wemos D1 来做一些简单的小数学运算。
据我所知,双精度是可用的,所以我正在使用它——最大为 1.8*10^103。
但是当我尝试计算一个大约 5*10^8 的数字时,我得到了一个 ovf。
有什么想法吗?
void setup(){
Serial.begin(9600);
while(!Serial);
Serial.println("Hit any key to start math");
double te = 6800;
double res = te * te;
Serial.println(res);
te = 68000;
res = te * te;
Serial.println(res);
te = 680000;
res = te * te;
Serial.println(res);
}
void loop(){
}
打印
46240000.00
ovf
ovf
Arduino 确实支持 4 字节双精度数据类型。并且您的代码确实产生了一个有效的双精度值,该值不会溢出(ovf)。
您看到的问题与 Arduino 实现 Serial.print()
函数的方式有关,它几乎就像一个支持浮点的半生不熟的 hack,不如 vprintf() that is available in avr-libc. You can see the source code here 可靠对于大于 4294967040.0 或小于 -4294967040.0 的任何值,打印 ovf
。我认为 ESP8266 Arduino Core 已经解决了这个问题,而不是继承 Arduino 的丑陋实现 Serial.print()
,但显然不是。
幸运的是,ESP8266 Arduino Core 确实有一个 Serial.printf()
方法可以提供更好的浮点渲染。此代码将显示您的号码确实是 double 数据类型的有效号码。
void setup(){
Serial.begin(9600);
while(!Serial);
double te = 68000;
double res = te * te;
Serial.println(res); //this will produce 'ovf'
Serial.printf("Result=%f\n", res); //this will produce correct 4624000000.000000
}
请注意,Serial.printf()
是 ESP8266 的特定实现,以支持标准库中的全浮点 vprintf()
。它不适用于标准 Arduino 开发板。
对于 Arduino 板,有一种方法可以使用继承自 vprintf()
的 sprintf()
来打印正确的浮点数,并在代码编译过程中对链接器选项进行一些改动。我有一个博客 post Do you know Arduino - sprintf() and floating point 谈论如何做到这一点。
我正在使用基于 ESP8266 wifi 芯片和 Arduino C 框架的 Wemos D1 来做一些简单的小数学运算。 据我所知,双精度是可用的,所以我正在使用它——最大为 1.8*10^103。 但是当我尝试计算一个大约 5*10^8 的数字时,我得到了一个 ovf。 有什么想法吗?
void setup(){
Serial.begin(9600);
while(!Serial);
Serial.println("Hit any key to start math");
double te = 6800;
double res = te * te;
Serial.println(res);
te = 68000;
res = te * te;
Serial.println(res);
te = 680000;
res = te * te;
Serial.println(res);
}
void loop(){
}
打印
46240000.00
ovf
ovf
Arduino 确实支持 4 字节双精度数据类型。并且您的代码确实产生了一个有效的双精度值,该值不会溢出(ovf)。
您看到的问题与 Arduino 实现 Serial.print()
函数的方式有关,它几乎就像一个支持浮点的半生不熟的 hack,不如 vprintf() that is available in avr-libc. You can see the source code here 可靠对于大于 4294967040.0 或小于 -4294967040.0 的任何值,打印 ovf
。我认为 ESP8266 Arduino Core 已经解决了这个问题,而不是继承 Arduino 的丑陋实现 Serial.print()
,但显然不是。
幸运的是,ESP8266 Arduino Core 确实有一个 Serial.printf()
方法可以提供更好的浮点渲染。此代码将显示您的号码确实是 double 数据类型的有效号码。
void setup(){
Serial.begin(9600);
while(!Serial);
double te = 68000;
double res = te * te;
Serial.println(res); //this will produce 'ovf'
Serial.printf("Result=%f\n", res); //this will produce correct 4624000000.000000
}
请注意,Serial.printf()
是 ESP8266 的特定实现,以支持标准库中的全浮点 vprintf()
。它不适用于标准 Arduino 开发板。
对于 Arduino 板,有一种方法可以使用继承自 vprintf()
的 sprintf()
来打印正确的浮点数,并在代码编译过程中对链接器选项进行一些改动。我有一个博客 post Do you know Arduino - sprintf() and floating point 谈论如何做到这一点。