Переполненное значение печатает не переполненное значение на Arduino - PullRequest
0 голосов
/ 15 ноября 2018

Прежде всего, я знаю проблему с кодом и как заставить его работать. Я в основном ищу объяснение, почему мой вывод такой, какой он есть.

Следующий фрагмент кода повторяет поведение:

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println("start");
  for(int i = 0; i < 70000; i++) {
    if((i % 2000) == 0)
      Serial.println(i);
  }
}

Очевидно, что цикл for будет работать вечно, потому что i переполнится при 32 767. Я ожидаю, что он переполнится и напечатает -32000.

Expected|   Actually printed
0       |   0                                       
2000    |   2000                                    
4000    |   4000                                    
...     |   ...                                     
30000   |   30000                                   
32000   |   32000                                   
-32000  |   33536                                   
-30000  |   35536       

Похоже, что он печатает фактические итерации, поскольку, если вы переполнитесь и будете считать до -32000, у вас будет 33536 итераций, но я не могу понять, как можно распечатать 33536.

То же самое происходит каждые 65536 итераций:

95536   |   161072  |   226608  |   292144  |   357680
97536   |   163072  |   228608  |   294144  |   359680
99072   |   164608  |   230144  |   295680  |   361216
101072  |   166608  |   232144  |   297680  |   363216

EDIT

Когда я изменяю цикл, добавляя 10.000 за каждую итерацию, и печатаю только каждые 1.000.000, чтобы ускорить его, происходит сбой Arduino (или, по крайней мере, остановка печати) на уровне 2.147.000.000. Что, кажется, указывает на 32-битную идею svtag **

EDIT2

Правки, которые я сделал для проверки 2.147.000.000:

void loop() {
  Serial.println("start");
  for(int i = 0; i < 70000; i+=10000) {
    if((i % 1000000) == 0)
      Serial.println(i);
  }
}

Они работают в том же тренде, что и в предыдущем примере, печатая 0, 1000000, 2000000,...

Однако, когда я обновляю пакет AVR с 1.6.17 до последнего 1.6.23, я получаю только 0. Исходный пример (% 2000 & i++) все еще дает тот же вывод.

1 Ответ

0 голосов
/ 15 ноября 2018

Компилятор, возможно, автоматически преобразовал i в usigned int, когда вы выполняете println, или значение переходит на неправильную перегрузку. Попробуйте использовать Serial.println ((int) i);

...