Arduino ESP8266“;ovf";在做小的数学双题时
我正在使用基于ESP8266 wifi芯片和Arduino C框架的Wemos D1做一些简单的小计算。 据我所知,双精度是可用的,所以我使用它-最大值约为1.8*10^103。 但当我试图计算一个5*10^8左右的数字时,我得到了一个ovf。 有什么想法吗Arduino ESP8266“;ovf";在做小的数学双题时,arduino,esp8266,Arduino,Esp8266,我正在使用基于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;
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()
函数的方式有关,该函数几乎像一个半熟的黑客一样支持浮点运算,并且不像avr libc中提供的那样可靠。对于大于4294967040.0或小于-4294967040.0的任何内容,您都可以看到打印ovf的源代码。我认为ESP8266 Arduino Core已经修复了这个问题,而不是继承了ArduinoSerial.print()
的丑陋实现,但显然不是
幸运的是,ESP8266 Arduino内核有一个Serial.printf()
方法,可以提供更好的浮点渲染。此代码将显示您的数字确实是双精度数据类型的有效数字
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()
,在代码编译过程中通过一些链接器选项打印正确的浮点。我有一篇博文讨论了如何做到这一点。Brill,谢谢你有深刻见解的回答!事实上,我正在做一些更多的机器学习(SVM)数学的背景,可能会溢出,但调试这是第一步-再次感谢!