2

Is there any way to recognize whether an unpredictable value would exceed the max value of a numeric type? In the following code the result of the if clause is always false and no exception is raised.

procedure TForm1.FormClick(Sender: TObject);
var
  _Integer1, _Integer2: Integer;
begin
  _Integer1 := MaxInt;

  _Integer2 := _Integer1 + _Integer1;

  if _Integer2 > MaxInt then
  begin
    Caption := '';
  end
  else
  begin
    Caption := IntToStr(_Integer2); // -2
  end;
end;
SHIN JaeGuk
  • 494
  • 1
  • 5
  • 14

2 Answers2

4

Your _Integer2 > MaxInt will never return True because it is impossible. The value of an Integer cannot ever be greater than the greatest possible value of an Integer.

However, you can enable overflow checking:

var
  x, y, z: Integer;
begin

  {$Q+}                         // enable overflow checking

  x := MaxInt div 2;
  y := MaxInt div 4;

  z := x + y;                   // fine

  ShowMessage(z.ToString);

  x := MaxInt div 2;
  y := 3 * (MaxInt div 4);

  try
    z := x + y;                 // exception
    ShowMessage(z.ToString);    // won't run
  except
    on EIntOverflow do
      ShowMessage('Integer overflow.');
  end;

Here I enable overflow checking locally using a compiler directive: {$Q+}. If you want to use overflow checking in a particular function or procedure, you can use this together with a resetter, like in this answer but opposite.

You can also turn it on for an entire project using Project > Options > Delphi Compiler > Compiling > Runtime errors > Overflow checking. Just remember that this setting is per configuration (for instance, debug vs. release).

Andreas Rejbrand
  • 105,602
  • 8
  • 282
  • 384
2

You can save the result in a larger integer type, eg:

procedure TForm1.FormClick(Sender: TObject);
var
  _Integer1: Integer;
  _Integer2: Int64;
begin
  _Integer1 := MaxInt;

  _Integer2 := Int64(_Integer1) + _Integer1;

  if _Integer2 > MaxInt then
  begin
    Caption := '';
  end
  else
  begin
    Caption := IntToStr(_Integer2);
  end;
end;

Or, you can calculate the available number space manually, eg:

procedure TForm1.FormClick(Sender: TObject);
var
  _Integer1, _Integer2: Integer;
begin
  _Integer1 := MaxInt;

  if (MaxInt - _Integer1) < _Integer1 then
  begin
    Caption := '';
  end
  else
  begin
    _Integer2 := _Integer1 + _Integer1;
    Caption := IntToStr(_Integer2);
  end;
end;

Or, you can enable Overflow Checking, as shown in Andreas' answer.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770