如何检测整数溢出

时间:2015-12-30 11:10:32

标签: arduino integer-overflow

我正在开发一个带LCD和键盘的项目。用户将从键盘输入整数值(例如学生编号)。数字将通过键盘的按键并排打印到LCD上。只打印十进制数字,而不是A,B,C,D,#和*。在按下#键之前,程序不会继续。用户输入完值后按#键程序将继续。

以下是我的一些代码:

  #include <LiquidCrystal_I2C.h>
  #include <Keypad.h>

  const byte ROWS = 4; //four rows
  const byte COLS = 4; //four columns
  char keys[ROWS][COLS] = {
    {'1', '4', '7', '*'},
    {'2', '5', '8', '0'},
    {'3', '6', '9', '#'},
    {'A', 'B', 'C', 'D'}
  };

  byte rowPins[ROWS] = {41, 43, 45, 47};
  byte colPins[COLS] = {40, 42, 44, 46};
  Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS);

  LiquidCrystal_I2C lcd(0x3F, 20, 4);

  void setup() {
     lcd.begin();
  }

  void loop(){

  boolean pressedENTER = false;
  int studentsNUMBER=0;
  int keyENTERED;
  byte limit=0;
  do {
    int key = keypad.getKey();
    if (key != NO_KEY) {
      switch (key) {
        case '#': // this key will be used as ENTER key
          {
            pressedENTER = true;
            break;
          }
        case '*':
          break;
        case 'A':
          break;
        case 'B':
          break;
        case 'C': // C will clear LCD and set studentsNUMBER to 0
            studentsNUMBER=0;
            limit=0;
            lcd.clear();
          break;
        case 'D':
          break;
        default:
          keyENTERED = key - 48;
          limit++;
          if (studentsNUMBER > 3276){
            if (keyENTERED > 7){
              limit++;
            }
          }

          if (limit<=5){

              lcd.print(keyPRESSED);
              studentsNUMBER = (studentsNUMBER * 10) + keyPRESSED;
              if (studentsNUMBER < 0 or studentsNUMBER > 32767){
                studentsNUMBER=0;
                limit=0;
                lcd.clear()
                lcd.print(F("Value exceeded limits"));
                delay(1000);
            }  
          }
          break;
      }
    }
  }
  while (pressedENTER == false);
  lcd.clear();
  lcd.print(F("You entered:"));
  lcd.setCursor(0,1);
  lcd.print(studentsNUMBER);
  delay(2000);
  // program continues to do something..
  }

除整数溢出问题外,一切正常。让我澄清一下:如果输入介于0和32767之间,那就OK了。我的代码控制值是否介于0和32767之间。

但在这种情况下:

用户按下3(学生数量现在等于3)

用户按下3(学生数量现在等于33)

用户按3(studentsNUMBER现在等于333)

用户按下3(学生数量现在等于3333)

(这是问题的开始)

用户按3(学生数量现在等于33333 (超出整数限制但我无法避免)

非常感谢任何建议。

1 个答案:

答案 0 :(得分:0)

代码中的逻辑缺陷

您需要清楚地了解溢出/下溢的工作原理,

  if (studentsNUMBER < 0 or studentsNUMBER > 32767){
    ...
  }

您已将studentsNUMBER声明为integer,其最大值可以是 32767 。现在您要比较studentNUMBER > 32767studentNUMBER将永远无法超越限制。

建议

请注意,一旦出现溢出/下溢,就会发生Undefined行为,并且您的程序可以执行任何异常操作。

克服这种情况的许多方法之一可以是,

long result, 
int studentNUMBER, keyENTERED;
...
result = (studentsNUMBER * 10) + keyENTERED;
if (result > 32767)
{
    // overflow occurred 
}

希望你能得到一个概念。