我正在尝试在Arduino UNO上执行算法,它需要带有一些大数字的const表,有时,我得到溢出值。这个号码就是这种情况:628331966747.0
好的,这是一个很大的,但它的类型是float(32位),其中最大值是3.4028235e38。理论上它应该有效吗?
我能对此做些什么?你知道解决方案吗?
编辑:在Arduino UNO上,double是exaclty与浮动相同的类型(32位)
以下是导致错误的代码:
float A;
void setup() {
A = 628331966747.0;
Serial.begin(9600);
}
void loop() {
Serial.println(A);
delay(1000);
}
打印“ovf,ovf,...,ovf”
答案 0 :(得分:3)
常量本身没有任何问题(除了相当乐观的有效数字之外),但问题在于Arduino库支持打印浮点值的实现。 Print::printFloat()
包含以下前置条件测试:
if (isnan(number)) return print("nan");
if (isinf(number)) return print("inf");
if (number > 4294967040.0) return print ("ovf"); // constant determined empirically
if (number <-4294967040.0) return print ("ovf"); // constant determined empirically
似乎有意限制了可打印值的范围,以便可能降低复杂性和代码大小。随后的代码揭示了原因:
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
n += print(int_part);
稍微简化的实现要求整数部分的绝对值本身是32位整数。
令人担忧的事情可能是评论“不断根据经验确定”,而这表明价值是通过反复试验得出的,而不是对数学的理解!人们不禁要问,为什么这些值没有用INT_UMAX
定义。
有一个建议的“修复”描述为here,但它至少不会起作用,因为它将整数abs()
函数应用于double
参数number
,仅当整数部分小于限制性更强MAX_INT
时才会起作用。作者发布了一个zip文件的链接,其中包含一个看起来更有可能工作的修复程序(有证据表明至少有测试!)。