我正在调试Arduino中的“大”程序。在某些时候它开始抛出奇怪的结果,所以我跟着它进行了一个不应该给出负数的操作。 结果应该是248,625,因为它存储在一个int变量中(给我相同的-79)。我已经尝试过铸造int并应用ceil,floor,但没有成功。 任何帮助将不胜感激。
调试打印:
B -> (255*195)/200+0 = -79
代码:
// the setup routine runs once when you press reset:
void setup() {
Serial.begin(115200);
}
// the loop routine runs over and over again forever:
void loop() {
int _num_steps = 200;
int _current_step = 195;
int _delta_B = 255;
int currentValues_B = 0;
Serial.print(" B -> ");
Serial.print("(");
Serial.print(_delta_B);
Serial.print("*");
Serial.print(_current_step);
Serial.print(")/");
Serial.print(_num_steps);
Serial.print("+");
Serial.print(currentValues_B);
Serial.print(" = ");
Serial.println(((_delta_B*_current_step) / _num_steps) + currentValues_B);
while(true){}
}
答案 0 :(得分:2)
我的猜测是你的设备运行16位整数。如果我们用16位有符号整数和溢出进行数学运算:
True
您可以通过打印sizeof(int)
来验证整数的大小答案 1 :(得分:2)
https://www.arduino.cc/en/Reference/Int
在Arduino Uno(以及其他基于ATMega的主板)上,一个int存储了一个 16位(2字节)值。这产生了-32,768到32,767的范围 (最小值-2 ^ 15,最大值(2 ^ 15) - 1)。
你可以尝试很长时间(在Arduino上是4字节)。我不一定会看到你打算做什么,但这也不会永远增长。如果它们可以永久增长,您需要处理包裹(或重置间隔或其他)的情况。此外,如果该值不应该变为负数,则可以使用无符号原始数据类型并将其正范围加倍。
答案 2 :(得分:1)
正如其他用户在评论中指出的那样,这是一个溢出问题。 鉴于" int"," long"等根据定义仅具有固定的最小位数(并且int最小数为16),则存在此问题。 可能你以前从未遇到过这个问题,因为现在有时候用32位实现int。
要确保每次都知道你的int类型使用的位数,你可以使用这样的东西:
typedef int32_t myint;
typedef u_int32_t myuint;
然后只使用myint。通过这种方式,您可以确切地知道所使用的位数,如果您决定根据一些新需求更改实现,则可以在一个位置更改它。
答案 3 :(得分:1)
由于int
使用16位n Arduino表示,因此您必须依靠基本数学来获得所需的答案。
您正在尝试计算(A*B)/C
。
(A*B)/C = ((k1*C+a) * (k2*C+b)/C
,其中
k1 = A/C
和a = A%C
,以及k2 = B/C
和b = B%C
。
(k1*C+a) * (k2*C+b)
等于(k1*k2*C*C + b*k1*C + a*k2*C + a*b)
如果按C
划分,则获得k1*k2*C + b*k1 + a*k2 + (a*b)/C
。
该数字应保持在16位数的范围内。
在64位计算机上演示该想法的示例程序:
#include <iostream>
int main()
{
int A = 255;
int B = 195;
int C = 200;
int k1 = A/C;
int a = A%C;
int k2 = B/C;
int b = B%C;
std::cout << k1*k2*C << std::endl;
std::cout << k1*b << std::endl;
std::cout << k2*a << std::endl;
std::cout << a*b << std::endl;
int sum = k1*k2*C + k1*b + k2*a + (a*b)/C;
std::cout << sum << std::endl;
std::cout << (A*B)/C << std::endl;
}
输出:
0
195
0
10725
248
248