Search code examples
delphicase

Low bound exceeds high bound & Duplicate case label if you swap'em cntCaseTbl(Z : Int64): Int64; Error in Case Table


I'm getting this error on the code below:

Low bound exceeds high bound

If you swap them, you get a different error:

Duplicate case label

What can I do?

I've tried all of them without Int64() and with Int64(), but it didn't help.

Try for yourself, errors exist no matter if you type cast or not.

There's several ways to do this below, but I want to know why this code errors the way it does:

Delphi can not use below because it can not achieve 64-bit processing on case statements.

function cntCaseTbl(Z: Int64): Int64;
  begin
    case Abs(Z) of
      0..9: Exit(1);
      10..99: Exit(2);
      100..999: Exit(3);
      1000..9999: Exit(4);
      10000..99999: Exit(5);
      100000..999999: Exit(6);
      1000000..9999999: Exit(7);
      10000000..99999999: Exit(8);
      100000000..999999999: Exit(9);
      1000000000..9999999999: Exit(10);
      10000000000..99999999999: Exit(11);
      100000000000..999999999999: Exit(12);
      1000000000000..9999999999999: Exit(13);
      10000000000000..99999999999999: Exit(14);
      100000000000000..999999999999999: Exit(15);
      1000000000000000..9999999999999999: Exit(16);
      10000000000000000..99999999999999999: Exit(17);
      100000000000000000..999999999999999999: Exit(18);
      1000000000000000000..9223372036854775807: Exit(19);
    end;
  end;

Solution

  • On line 131, 10000000000 and 99999999999 are Integers that are being type-casted to Int64, and they are both outside of the range of Integer, so they are overflowing before being casted, thus causing the 1st value to be less than the 2nd value, hence the error.

    Same with the other lines, too.

    This is described in Delphi's documentation:

    Case Statements

    The case statement may provide a readable alternative to deeply nested if conditionals. A case statement has the form:

    case selectorExpression of
      caseList1: statement1;
       ...
      caseListn: statementn;
    end
    

    where selectorExpression is any expression of an ordinal type smaller than 32 bits (string types and ordinals larger than 32 bits are invalid) ...

    I would suggest getting rid of the case altogether and just use a loop instead, eg:

    function cntCaseTbl(Z: Int64): Int64;
    begin
      Result := 0;
      Z := Abs(Z);
      while Z > 0 do begin
        Inc(Result);
        Z := Z div 10;
      end;
    end;