SelfTest.pas

File name
C:\Users\Andreas Rejbrand\Documents\Dev\AlgoSim\SelfTest.pas
Date exported
Time exported
Formatting processor
TPascalFormattingProcessor
unit SelfTest;

{ **************************************************************************** }
{ Rejbrand AlgoSim Automatic Tests                                             }
{ Copyright © 2019-2022 Andreas Rejbrand                                       }
{ https://english.rejbrand.se/                                                 }
{ **************************************************************************** }

{$DEFINE QuickTest}

interface

uses
  Windows, SysUtils, Types, Classes, Graphics, ASNum, ASKernelDefs, ASKernel,
  ASExpression, ASObjects, ASStructs, ASObjStore, ASPropMan, ASPropStores,
  ASFcnMgr, ASFcnExp, ASExecutionContext, ASFormatters, ASFunctions,
  ASTokenizer, ASParser, ASStrFcns, Generics.Defaults, Generics.Collections,
  ASColors, ASPixmap, ASSounds, UITypes;

type
  TSelfTestProgressEvent = procedure(ATotal, APerformed, ASucceeded,
    AFailed: Integer) of object;
  TSelfTestChapterEvent = procedure(AChapterNumber: Integer;
    const AChapterName: string) of object;

procedure Run(AKernel: TASKernel; AProgressEvent: TSelfTestProgressEvent = nil;
  AChapterEvent: TSelfTestChapterEvent = nil);

implementation

uses
  Math, StrUtils, DateUtils, Character, Clipbrd, MatLits, Registry, IOUtils,
  PngImage, ASMidi, SelfTestUI;

const
  TotalCount = 495436;

{$REGION 'Infrastructure'}

var
  ElapsedTime: Double;

type
  TSelfTester = class
  strict private
  type
    TTestItem = record
      Expr: string;
      Expected, Actual: string;
      constructor Create(const AExpr, AExpected, AActual: string);
      function ToString: string;
    end;
  const
    RealMatrixNames = AnsiString('ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖabcdfghjklmnopqrstuvwxyzåä');
    ComplexMatrixNames = AnsiString('ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖabcdfghjklmnopqrstuvwxyzåäöüë');
    CharSamples = 'GHNÖÅÉÏÔÂÑΓΒΘЧmbåñõéïγεφю75610½¼¾⅛ⅷ፹Ⅳ⑭〤⑽⒖㉑.,!?-;:()∫∅∂⌬⌨'#32#9#13#10#$A0#1#2#7#24#27#28#31;
  var
    FKernel: TASKernel;
    FTestCount,
    FSuccessCount,
    FFailCount: Integer;
    FChapterNumber: Integer;
    FFailList: TList<TTestItem>;
    FEps: TASR;
    FProgressEvent: TSelfTestProgressEvent;
    FChapterEvent: TSelfTestChapterEvent;
    FLastStatTime: UInt64;
    procedure Log(const AText: string; const AClass: string = '');
    procedure SendProgress(AForce: Boolean = False);
    procedure Chapter(const AChapterName: string);
    procedure Test(ALineNumber: Integer; const AExpr: string; const AExpected: TAlgosimObject;
      ATestSingleLine: Boolean = False; const AExpSingleLine: string = ''); overload;
    procedure Test(ALineNumber: Integer; const AExpr: string; const AExpected: ExceptClass;
      const AErrorMessage: string = ''); overload;
    procedure Test(ALineNumber: Integer; const AExpr: string; const AExpected: TASI;
      TestSL: Boolean = False; const SL: string = ''); overload;
    procedure Test(ALineNumber: Integer; const AExpr: string; const AExpected: TRationalNumber;
      TestSL: Boolean = False; const SL: string = ''); overload;
    procedure Test(ALineNumber: Integer; const AExpr: string; const AExpected: TASR;
      TestSL: Boolean = False; const SL: string = ''); overload;
    procedure Test(ALineNumber: Integer; const AExpr: string; const AExpected: TASC;
      TestSL: Boolean = False; const SL: string = ''); overload;
    procedure Test(ALineNumber: Integer; const AExpr: string; const AExpected: string;
      TestSL: Boolean = False; const SL: string = ''); overload;
    procedure Test(ALineNumber: Integer; const AExpr: string; const AExpected: array of TASR); overload;
    procedure Test(ALineNumber: Integer; const AExpr: string; const AExpected: array of TASC); overload;
    procedure Test(ALineNumber: Integer; const AExpr: string; AColCount: Integer; const AExpected: array of TASR); overload;
    procedure Test(ALineNumber: Integer; const AExpr: string; AColCount: Integer; const AExpected: array of TASC); overload;
    procedure Test(ALineNumber: Integer; const AExpr: string; const AExpected: TRGB;
      TestSL: Boolean = False; const SL: string = ''); overload;
    procedure Test(ALineNumber: Integer; const AExpr: string; const AExpected: THSV;
      TestSL: Boolean = False; const SL: string = ''); overload;
    procedure Test(ALineNumber: Integer; const AExpr: string; const AExpected: THSL;
      TestSL: Boolean = False; const SL: string = ''); overload;
        procedure Test(ALineNumber: Integer; const AExpr: string; const AExpected: Boolean); overload;
    procedure Test(ALineNumber: Integer; const AExpr: string; const AExpected: TASOSignal); overload;
    procedure Test(ALineNumber: Integer; const AExpr: string; const AExpected: TASOSignal;
      const AErrorMessage: string); overload;
    procedure TestSL(ALineNumber: Integer; const AExpr, AExpected: string);
    procedure TestML(ALineNumber: Integer; const AExpr, AExpected: string);
    procedure TestDuration(ALineNumber: Integer; const AMaxDur: Double); overload;
    procedure TestDuration(ALineNumber: Integer; const AMinDur, AMaxDur: Double); overload;
    procedure TestExternal(ALineNumber: Integer; const ATestName: string; AAssertion: Boolean);
    procedure TestNumFmt(ALineNumber: Integer; const ARatValue: string; ANumberFormat: TNumberFormat;
      ANumDigits: Integer; const AExpOutput: array of string); overload;
    procedure TestNumFmt(ALineNumber: Integer; const ARatValue: string; ANumberFormat: TNumberFormat;
      const AExpOutput: array of string); overload;
    procedure Eps(const AEpsilon: TASR = 0);
    function _ASOEq(A, B: TAlgosimObject): Boolean;
    procedure TestSeq;
    function Name(const AFirst, ALast: string): TAlgosimStructure;
    function Person(const AFirstName, ALastName, ASex: string;
      AAge: Integer): TAlgosimStructure;
    function Jane: TAlgosimStructure;
    function Mike: TAlgosimStructure;
    function John: TAlgosimStructure;
    function Sarah: TAlgosimStructure;
    function Mary: TAlgosimStructure;
    function SPerson(const AName: string; AAge: Integer;
      const ASex: string = ''): TAlgosimStructure;
    procedure TestRealMatrixQ(ALineNumber: Integer; const AFcnName: string;
      const APositives: AnsiString);
    procedure TestRealMatrixQImplies(ALineNumber: Integer; const ALeft, ARight: string);
    procedure TestComplexMatrixQ(ALineNumber: Integer; const AFcnName: string;
      const APositives: AnsiString);
    procedure TestComplexMatrixQImplies(ALineNumber: Integer; const ALeft, ARight: string);
    function LoremIpsum(AParagraphs: Integer): string;
    procedure TestCharType(ALineNumber: Integer; const AFcnName: string;
      const APositives: string);
    procedure TestDefVars;
    procedure FailListNotify(Sender: TObject; const Item: TSelfTester.TTestItem;
      Action: TCollectionNotification);
  public
    constructor Create(AKernel: TASKernel);
    procedure RunTests;
    destructor Destroy; override;
    property OnProgress: TSelfTestProgressEvent read FProgressEvent write FProgressEvent;
    property OnChapter: TSelfTestChapterEvent read FChapterEvent write FChapterEvent;
  end;

procedure Run(AKernel: TASKernel; AProgressEvent: TSelfTestProgressEvent;
  AChapterEvent: TSelfTestChapterEvent);
begin
  with TSelfTester.Create(AKernel) do
    try
      OnProgress := AProgressEvent;
      OnChapter := AChapterEvent;
      RunTests;
    finally
      Free;
    end;
end;

{ TSelfTester.TTestItem }

constructor TSelfTester.TTestItem.Create(const AExpr, AExpected,
  AActual: string);
begin
  Self.Expr := AExpr;
  Self.Expected := AExpected;
  Self.Actual := AActual;
end;

function TSelfTester.TTestItem.ToString: string;
begin
  Result :=
    '--------------------------------------------'#13#10 +
    'Test failed.'#13#10 +
    Self.Expr + #13#10 +
    '  Expected: ' + Self.Expected + #13#10 +
    '    Actual: ' + Self.Actual + #13#10 +
    '--------------------------------------------'#13#10;
end;

{ TSelfTester }

procedure TSelfTester.Chapter(const AChapterName: string);
begin
  Inc(FChapterNumber);
  if Assigned(FChapterEvent) then
    FChapterEvent(FChapterNumber, AChapterName);
end;

constructor TSelfTester.Create(AKernel: TASKernel);
begin
  FFailList := TList<TTestItem>.Create;
  FFailList.OnNotify := FailListNotify;
  FKernel := AKernel;
  FKernel.ClearAllVars;
  FKernel.LoadDefVars;
  FKernel.ClearAllBuffers;
  FKernel.ClearCommandHistory;
  FEps := -1;
end;

destructor TSelfTester.Destroy;
begin
  FFailList.Free;
  FKernel.ClearCommandHistory;
  FKernel.ClearAllBuffers;
  FKernel.ClearAllVars;
  FKernel.LoadDefVars;
  inherited;
end;

procedure TSelfTester.Eps(const AEpsilon: TASR);
begin
  FEps := AEpsilon;
end;

procedure TSelfTester.FailListNotify(Sender: TObject;
  const Item: TSelfTester.TTestItem; Action: TCollectionNotification);
begin

end;

procedure TSelfTester.Log(const AText: string; const AClass: string);
begin
  FKernel.Perform(CLIENT_COMMAND_PRINT, 0, NativeInt(PChar(AText)),
    NativeInt(PChar(AClass)), 0);
end;

function TSelfTester.LoremIpsum(AParagraphs: Integer): string;
const
  Para =
    'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor ' +
    'incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis ' +
    'nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ' +
    'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu ' +
    'fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in ' +
    'culpa qui officia deserunt mollit anim id est laborum.';
var
  p: PChar;
  i: Integer;
const
  CRLF: string = #13#10;
begin

  if AParagraphs < 1 then
    Exit('');

  SetLength(Result, AParagraphs * Para.Length + (AParagraphs - 1) * CRLF.Length);

  p := PChar(Result);

  for i := 1 to AParagraphs do
  begin
    MoveChars(Para[1], p^, Para.Length);
    Inc(p, Para.Length);
    if i < AParagraphs then
    begin
      MoveChars(CRLF[1], p^, CRLF.Length);
      Inc(p, CRLF.Length);
    end;
  end;

end;

procedure TSelfTester.RunTests;
var
  OldSeed: Integer;
begin
  SendProgress;
  OldSeed := RandSeed;
  RandSeed := 9617237;
  try
    TestSeq;
  finally
    RandSeed := OldSeed;
  end;
  SendProgress(True);
end;

function TSelfTester.Name(const AFirst, ALast: string): TAlgosimStructure;
begin
  Result := TAlgosimStructure.CreateWithValue(
    ['first', 'last'],
    [ASO(AFirst), ASO(ALast)]
  );
end;

function TSelfTester.Person(const AFirstName, ALastName, ASex: string; AAge: Integer): TAlgosimStructure;
begin
  Result := TAlgosimStructure.CreateWithValue(
    ['name', 'sex', 'age'],
    [Name(AFirstName, ALastName), ASO(ASex), ASOInt(AAge)]
  );
end;

function TSelfTester.Jane: TAlgosimStructure;
begin
  Jane := Person('Jane', 'Smith', 'female', 40);
end;

function TSelfTester.John: TAlgosimStructure;
begin
  John := Person('John', 'Stone', 'male', 69);
end;

function TSelfTester.Mary: TAlgosimStructure;
begin
  Mary := TAlgosimStructure.CreateWithValue(
    ['mother', 'father'],
    [Jane, Mike]
  );
end;

function TSelfTester.Mike: TAlgosimStructure;
begin
  Mike := Person('Mike', 'Doe', 'male', 45);
end;

function TSelfTester.Sarah: TAlgosimStructure;
begin
  Sarah := Person('Sarah', 'Lester', 'female', 25);
end;

procedure TSelfTester.SendProgress(AForce: Boolean);
begin
  if not AForce and (GetTickCount64 - FLastStatTime < 100) then
    Exit;
  if Assigned(FProgressEvent) then
  begin
    FProgressEvent(TotalCount, FTestCount, FSuccessCount, FFailCount);
  end;
  FLastStatTime := GetTickCount64;
end;

function TSelfTester.SPerson(const AName: string;
  AAge: Integer; const ASex: string): TAlgosimStructure;
begin
  if ASex.IsEmpty then
    Result := TAlgosimStructure.CreateWithValue(
      ['name', 'age'],
      [ASO(AName), ASOInt(AAge)]
    )
  else
    Result := TAlgosimStructure.CreateWithValue(
      ['name', 'age', 'sex'],
      [ASO(AName), ASOInt(AAge), ASO(ASex)]
    )
end;

procedure TSelfTester.Test(ALineNumber: Integer; const AExpr: string; const AExpected: array of TASR);
begin
  Test(ALineNumber, AExpr, ASO(TRealVector.Create(AExpected)));
end;

procedure TSelfTester.Test(ALineNumber: Integer; const AExpr, AExpected: string;
  TestSL: Boolean = False; const SL: string = '');
begin
  Test(ALineNumber, AExpr, ASO(AExpected), TestSL, SL);
end;

procedure TSelfTester.Test(ALineNumber: Integer; const AExpr: string; const AExpected: TASC;
  TestSL: Boolean; const SL: string);
begin
  Test(ALineNumber, AExpr, ASO(AExpected), TestSL, SL);
end;

procedure TSelfTester.Test(ALineNumber: Integer; const AExpr: string; const AExpected: TRationalNumber;
  TestSL: Boolean; const SL: string);
begin
  if TestSL then
    Test(ALineNumber, 'SetNumberFormat((' + AExpr + '), "fraction")', ASORat(AExpected), TestSL, SL)
  else
    Test(ALineNumber, AExpr, ASORat(AExpected), TestSL, SL);
end;

procedure TSelfTester.Test(ALineNumber: Integer; const AExpr: string; const AExpected: TASI;
  TestSL: Boolean; const SL: string);
begin
  Test(ALineNumber, AExpr, ASOInt(AExpected), TestSL, SL);
end;

procedure TSelfTester.Test(ALineNumber: Integer; const AExpr: string; const AExpected: TAlgosimObject;
  ATestSingleLine: Boolean = False; const AExpSingleLine: string = '');
var
  res: TAlgosimObject;
begin
  try
    Inc(FTestCount);
    try
      res := FKernel.Evaluate(AExpr);
    except
      on E: Exception do
      begin
        Inc(FFailCount);
        FFailList.Add(TTestItem.Create(ALineNumber.ToString + #9 + AExpr, AExpected.ClassName + '(' + AExpected.ToString + ')', E.ClassName + E.Message));
        Log(FFailList.Last.ToString, 'Error');
        Exit;
      end;
    end;
    if
      (res.ClassType = AExpected.ClassType) and
      _ASOEq(res, AExpected) and
      (not ATestSingleLine or res.GetAsSingleLineText(FKernel.FormatOptions).Equals(AExpSingleLine))
    then
      Inc(FSuccessCount)
    else
    begin
      Inc(FFailCount);
      if not (res.ClassType = AExpected.ClassType) or not _ASOEq(res, AExpected) then
      begin
        if res is TAlgosimFailure then
          FFailList.Add(TTestItem.Create(ALineNumber.ToString + #9 + AExpr, AExpected.ClassName + '(' + AExpected.ToString + ')', res.ClassName + '(' + TAlgosimFailure(res).FailureReason + ')'))
        else
          FFailList.Add(TTestItem.Create(ALineNumber.ToString + #9 + AExpr, AExpected.ClassName + '(' + AExpected.ToString + ')', res.ClassName + '(' + res.ToString + ')'))
      end
      else
        FFailList.Add(TTestItem.Create(ALineNumber.ToString + #9 + AExpr, AExpSingleLine, res.GetAsSingleLineText(FKernel.FormatOptions)));
      Log(FFailList.Last.ToString, 'Error');
    end;
  finally
    FEps := -1; // noexcept
    AExpected.Free;
    SendProgress;
  end;
end;

procedure TSelfTester.Test(ALineNumber: Integer; const AExpr: string; const AExpected: ExceptClass;
  const AErrorMessage: string);
var
  res: TAlgosimObject;
begin
  Inc(FTestCount);
  try
    res := FKernel.Evaluate(AExpr);
  except
    on E: Exception do
    begin
      if (E is AExpected) and (AErrorMessage.IsEmpty or E.Message.ToLower.Contains(AErrorMessage.ToLower)) then
        Inc(FSuccessCount)
      else
      begin
        Inc(FFailCount);
        if not (E is AExpected) then
          FFailList.Add(TTestItem.Create(ALineNumber.ToString + #9 + AExpr, AExpected.ClassName, E.ClassName))
        else
          FFailList.Add(TTestItem.Create(ALineNumber.ToString + #9 + AExpr, AExpected.ClassName + ': ' + AErrorMessage, E.ClassName + ': ' + E.Message));
        Log(FFailList.Last.ToString, 'Error');
      end;
      SendProgress;
      Exit;
    end;
  end;
  Inc(FFailCount);
  FFailList.Add(TTestItem.Create(ALineNumber.ToString + #9 + AExpr, AExpected.ClassName, res.ClassName + '(' + res.ToString + ')'));
  Log(FFailList.Last.ToString, 'Error');
  SendProgress;
end;

procedure TSelfTester.Test(ALineNumber: Integer; const AExpr: string; const AExpected: TASR;
  TestSL: Boolean; const SL: string);
begin
  Test(ALineNumber, AExpr, ASO(AExpected), TestSL, SL);
end;

procedure TSelfTester.Test(ALineNumber: Integer; const AExpr: string; const AExpected: array of TASC);
begin
  Test(ALineNumber, AExpr, ASO(TComplexVector.Create(AExpected)));
end;

procedure TSelfTester.Test(ALineNumber: Integer; const AExpr: string; AColCount: Integer;
  const AExpected: array of TASC);
begin
  Test(ALineNumber, AExpr, ASO(TComplexMatrix.Create(AExpected, AColCount)));
end;

procedure TSelfTester.Test(ALineNumber: Integer; const AExpr: string; AColCount: Integer;
  const AExpected: array of TASR);
begin
  Test(ALineNumber, AExpr, ASO(TRealMatrix.Create(AExpected, AColCount)));
end;

procedure TSelfTester.Test(ALineNumber: Integer; const AExpr: string; const AExpected: TRGB;
  TestSL: Boolean = False; const SL: string = '');
begin
  Test(ALineNumber, AExpr, ASO(AExpected), TestSL, SL);
end;

procedure TSelfTester.Test(ALineNumber: Integer; const AExpr: string; const AExpected: Boolean);
begin
  Test(ALineNumber, AExpr, ASO(AExpected));
end;

procedure TSelfTester.Test(ALineNumber: Integer; const AExpr: string; const AExpected: TASOSignal);
begin
  Test(ALineNumber, AExpr, ASO(AExpected));
end;

procedure TSelfTester.Test(ALineNumber: Integer; const AExpr: string; const AExpected: TASOSignal;
  const AErrorMessage: string);
var
  res: TAlgosimObject;
begin
  Assert(AExpected = failure);
  Inc(FTestCount);
  try
    res := FKernel.Evaluate(AExpr);
  except
    on E: Exception do
    begin
      Inc(FFailCount);
      FFailList.Add(TTestItem.Create(ALineNumber.ToString + #9 + AExpr, 'failure' + ' (' + AErrorMessage + ')', E.ClassName));
      Log(FFailList.Last.ToString, 'Error');
      SendProgress;
      Exit;
    end;
  end;
  if
    (res is TAlgosimFailure)
      and
    TAlgosimFailure(res).FailureReason.ToLower.Contains(AErrorMessage.ToLower)
  then
    Inc(FSuccessCount)
  else
  begin
    Inc(FFailCount);
    if not (res is TAlgosimFailure) then
      FFailList.Add(TTestItem.Create(ALineNumber.ToString + #9 + AExpr, 'failure', res.ClassName + '(' + res.ToString + ')'))
    else
      FFailList.Add(TTestItem.Create(ALineNumber.ToString + #9 + AExpr, 'failure (' + AErrorMessage + ')', TAlgosimFailure(res).FailureReason));
    Log(FFailList.Last.ToString, 'Error');
  end;
  SendProgress;
end;

procedure TSelfTester.Test(ALineNumber: Integer; const AExpr: string; const AExpected: THSL;
  TestSL: Boolean; const SL: string);
begin
  Test(ALineNumber, AExpr, ASO(AExpected), TestSL, SL);
end;

procedure TSelfTester.Test(ALineNumber: Integer; const AExpr: string; const AExpected: THSV;
  TestSL: Boolean; const SL: string);
begin
  Test(ALineNumber, AExpr, ASO(AExpected), TestSL, SL);
end;

procedure TSelfTester.TestCharType(ALineNumber: Integer; const AFcnName, APositives: string);
begin
  for var c in CharSamples do
    Test(ALineNumber, Format('%s("%s")', [AFcnName, c]), Pos(c, APositives) <> 0);
end;

procedure TSelfTester.TestComplexMatrixQ(ALineNumber: Integer; const AFcnName: string;
  const APositives: AnsiString);
var
  c: AnsiChar;
  x: set of AnsiChar;
begin
  x := [];
  for c in ComplexMatrixNames do
    Include(x, c);
  for c in APositives do
  begin
    Test(ALineNumber, Format('%s(%s)', [AFcnName, c]), True);
    Exclude(x, c);
  end;
  for c in x do
    Test(ALineNumber, Format('%s(%s)', [AFcnName, c]), False);
end;

procedure TSelfTester.TestComplexMatrixQImplies(ALineNumber: Integer;
  const ALeft, ARight: string);
begin
  for var c in ComplexMatrixNames do
    Test(ALineNumber, Format('%s(%s) ⇒ %s(%s)', [ALeft, c, ARight, c]), True);
end;

procedure TSelfTester.TestDefVars;
begin
  Eps; Test({LINENUM}574, 'e', 2.7182818284590452353602874);
  Eps; Test({LINENUM}575, 'π', 3.1415926535897932384626433);
       Test({LINENUM}576, 'ℎ', 6.62607015E-34); // No blasted [epsilons] [here]! No, sir. Not one, single, bloody [epsilon]! Not one! [...] No, sir! Not one blasted, miserable ...
  Eps; Test({LINENUM}577, 'ℏ', 6.62607015E-34 / (2*3.1415926535897932384626433));
  Test({LINENUM}578, 'i', ImaginaryUnit); Test({LINENUM}0, 'i^2', TASC(-1));
  Test({LINENUM}579, 'true', True);
  Test({LINENUM}580, 'false', False);
  Test({LINENUM}581, 'otherwise', True);
  Test({LINENUM}582, '∅', TAlgosimSet.Create); Test({LINENUM}0, 'type(∅)', 'set'); Test({LINENUM}0, '#∅', 0); Test({LINENUM}0, '∅ = {}', True);
  Test({LINENUM}583, '¶', sLineBreak);
end;

procedure TSelfTester.TestDuration(ALineNumber: Integer; const AMinDur, AMaxDur: Double);
begin
  Test(ALineNumber,
    AMinDur.ToString(TFormatSettings.Invariant) +
    '≤' +
    ElapsedTime.ToString(TFormatSettings.Invariant) +
    '∧' +
    ElapsedTime.ToString(TFormatSettings.Invariant) +
    '≤' +
    AMaxDur.ToString(TFormatSettings.Invariant),
    True
  );
end;

procedure TSelfTester.TestExternal(ALineNumber: Integer; const ATestName: string;
  AAssertion: Boolean);
begin
  if AAssertion then
    Inc(FSuccessCount)
  else
  begin
    Inc(FFailCount);
    FFailList.Add(TTestItem.Create(ALineNumber.ToString + #9 + ATestName, 'Success', 'Failure'));
    Log(FFailList.Last.ToString, 'Error');
  end;
end;

procedure TSelfTester.TestDuration(ALineNumber: Integer; const AMaxDur: Double);
begin
  Test(ALineNumber,
    ElapsedTime.ToString(TFormatSettings.Invariant) +
    '≤' +
    AMaxDur.ToString(TFormatSettings.Invariant),
    True
  );
end;

procedure TSelfTester.TestSL(ALineNumber: Integer; const AExpr, AExpected: string);
begin
  Test(ALineNumber, 'AsSingleLine(' + AExpr + ')', AExpected);
end;

procedure TSelfTester.TestML(ALineNumber: Integer; const AExpr, AExpected: string);
begin
  Test(ALineNumber, 'AsMultiLine(' + AExpr + ')', AExpected);
end;

procedure TSelfTester.TestNumFmt(ALineNumber: Integer; const ARatValue: string;
  ANumberFormat: TNumberFormat; const AExpOutput: array of string);
begin
  TestNumFmt(ALineNumber, ARatValue, ANumberFormat, -1, AExpOutput);
end;

procedure TSelfTester.TestNumFmt(ALineNumber: Integer; const ARatValue: string;
  ANumberFormat: TNumberFormat; ANumDigits: Integer;
  const AExpOutput: array of string);

const
  NumFmtStrs: array[TNumberFormat] of string =
    ('default', 'fraction', 'fixed', 'scientific', 'power');

type
  TPrettyExpTestMode = (petmImplicit, petmOn, petmOff);

const
  PrettyExpTestModes = [Low(TPrettyExpTestMode)..High(TPrettyExpTestMode)];

  function ApplySettings(const S: string; AImplicitDef: Boolean;
    APrettyExp: TPrettyExpTestMode; ADigitGrouping: Integer): string;
  begin
    Result := S;
    if not AImplicitDef then
      Result := Format('SetNumberFormat(%s, "%s")', [Result, NumFmtStrs[ANumberFormat]]);
    if ANumDigits <> -1 then
      Result := Format('(%s) \ %d', [Result, ANumDigits]);
    if APrettyExp <> petmImplicit then
      Result := Format('SetPrettyExp(%s, %s)', [Result, IfThen(APrettyExp = petmOn, 'true', 'false')]);
    if ADigitGrouping <> -1 then
      Result := Format('SetDigitGrouping(%s, %d)', [Result, ADigitGrouping]);
  end;

  function ForceRat(const S: string): string;
  begin
    Result := Format('ToFraction(%s)', [S]);
  end;

  function ForceReal(const S: string): string;
  begin
    Result := Format('RealNumber(%s)', [S]);
  end;

  function ForceCplx(const S: string): string;
  begin
    Result := Format('ComplexNumber(%s)', [S]);
  end;

  function Unpretty(const S: string; APETM: TPrettyExpTestMode): string;
  begin
    if APETM = petmOff then
      Result := S
        .Replace('⋅10^−', 'E−')
        .Replace('⋅10^', 'E' + IfThen(ANumberFormat = nfExponent, '+'))
    else
      Result := S;
  end;

  function DoDigGr(const S: string; ADigGr: Integer): string;

    procedure DeE(var S: string);
    var
      i: Integer;
    begin
      i := S.Length;
      while (i > 0) and (S[i] <> 'E') and (S[i] <> 'e') and (S[i] <> DOT_OPERATOR) do
        Dec(i);
      if i > 0 then
        SetLength(S, i - 1);
    end;

  var
    p: Integer;
    Sgn, IntPart, IntPartGrpd, FracPart, FracPartGrpd, Suffix: string;
    i, j: Integer;
  begin

    if ADigGr < 1 then
      Exit(S);

    p := Pos('/', S);
    if p <> 0 then
      Exit(DoDigGr(Copy(S, 1, Pred(p)), ADigGr) + '/' + DoDigGr(Copy(S, Succ(p)), ADigGr));

    if IndexStr(Copy(S, 1, 1), [MINUS_SIGN, '-', '+']) <> -1 then
      Sgn := S[1];

    p := Pos('.', S);
    IntPart := Copy(S, 1 + Sgn.Length, IfThen(p = 0, MaxInt, p - 1 - Sgn.Length));
    if p <> 0 then
      FracPart := Copy(S, Succ(p));

    DeE(IntPart);
    DeE(FracPart);

    p := Pos('E', S);
    if p = 0 then
      p := Pos('e', S);
    if p = 0 then
      p := Pos(DOT_OPERATOR, S);
    if p <> 0 then
      Suffix := Copy(S, p);

    if not IntPart.IsEmpty then
    begin
      SetLength(IntPartGrpd, IntPart.Length + Ceil(IntPart.Length / ADigGr) - 1);
      j := 0;
      for i := 1 to IntPart.Length do
      begin
        if (i <> 1) and ((IntPart.Length - i + 1) mod ADigGr = 0) then
        begin
          Inc(j);
          IntPartGrpd[j] := FIGURE_SPACE;
        end;
        Inc(j);
        IntPartGrpd[j] := IntPart[i];
      end;
      Assert(j = IntPartGrpd.Length);
    end;

    if not FracPart.IsEmpty then
    begin
      SetLength(FracPartGrpd, FracPart.Length + Ceil(FracPart.Length / ADigGr) - 1);
      j := 0;
      for i := 1 to FracPart.Length do
      begin
        if (i <> 1) and (Pred(i) mod ADigGr = 0) then
        begin
          Inc(j);
          FracPartGrpd[j] := FIGURE_SPACE;
        end;
        Inc(j);
        FracPartGrpd[j] := FracPart[i];
      end;
      Assert(j = FracPartGrpd.Length);
    end;

    Result := Sgn + IntPartGrpd + IfThen(not FracPart.IsEmpty, '.') + FracPartGrpd + Suffix;

  end;

  function NZ(const S: string): Boolean;
  var
    i: Integer;
  begin
    for i := 1 to S.Length do
      if S[i].IsInArray(['E', 'e', DOT_OPERATOR]) then
        Break
      else if CharInSet(S[i], ['1'..'9']) then
        Exit(True);
    Result := False;
  end;

const
  Sgns: array[Boolean] of string = ('', MINUS_SIGN);

var
  dummy: Int64;
  i: Integer;
  LExpOutput: array[0..3] of string;
  ImplVals: array of Boolean;
  b: Boolean;
  petm: TPrettyExpTestMode;
  neg: Boolean;
  LRatValue: string;
  DigGr: Integer;

begin

  if not (Length(AExpOutput) in [1, 2, 3, 4]) then
    raise Exception.Create('TSelfTester.TestNumFmt: Incorrect array length.');

  for i := Low(LExpOutput) to High(LExpOutput) do
    LExpOutput[i] := AExpOutput[Min(i, High(AExpOutput))]
      .Replace('E', '⋅10^')
      .Replace(HYPHEN_MINUS, MINUS_SIGN)
      .Replace(#32, FIGURE_SPACE);

  if ANumberFormat = nfDefault then
    ImplVals := [False, True]
  else
    ImplVals := [False];

  for DigGr in TArray<Integer>.Create(-1, 0, 1, 2, 3, 4, 5) do
    for neg in [False, True] do
      for petm in PrettyExpTestModes do
        for b in ImplVals do
        begin

          if neg then
            LRatValue := '-' + ARatValue
          else
            LRatValue := ARatValue;

          if TryStrToInt64(ARatValue, dummy) then
          begin
            if LExpOutput[0] <> '*' then
              TestSL(ALineNumber, ApplySettings(LRatValue, b, petm, DigGr), Sgns[neg and NZ(LExpOutput[0])] + DoDigGr(Unpretty(LExpOutput[0], petm), DigGr));
          end
          else
            if LExpOutput[0] <> '!' then
              raise Exception.CreateFmt('TSelfTester.TestNumFmt: Cannot convert "%s" to an integer.', [LRatValue]);

          if (LExpOutput[1] <> '*') and not b then
            TestSL(ALineNumber, ApplySettings(ForceRat(LRatValue), b, petm, DigGr), Sgns[neg and NZ(LExpOutput[1])] + DoDigGr(Unpretty(LExpOutput[1], petm), DigGr));
          if LExpOutput[2] <> '*' then
            TestSL(ALineNumber, ApplySettings(ForceReal(LRatValue), b, petm, DigGr), Sgns[neg and NZ(LExpOutput[2])] + DoDigGr(Unpretty(LExpOutput[2], petm), DigGr));
          if LExpOutput[3] <> '*' then
            TestSL(ALineNumber, ApplySettings(ForceCplx(LRatValue), b, petm, DigGr), Sgns[neg and NZ(LExpOutput[3])] + DoDigGr(Unpretty(LExpOutput[3], petm), DigGr));

        end;

end;

function Rat(p, q: TASI): TRationalNumber;
begin
  Result := TRationalNumber.Create(p, q);
end;

function fs(const S: string): string;
var
  i: Integer;
begin
  Result := S;
  for i := 1 to S.Length do
    if Result[i] = #32 then
      Result[i] := FIGURE_SPACE;
end;

function mm(const S: string): string;
var
  i: Integer;
begin
  Result := S;
  for i := 1 to S.Length do
    if Result[i] = '-' then
      Result[i] := MINUS_SIGN
    else if Result[i] = '*' then
      Result[i] := DOT_OPERATOR;
end;


function TSelfTester._ASOEq(A, B: TAlgosimObject): Boolean;
begin
  if FEps >= 0 then
    Result := SameASO(A, B, FEps)
  else
    Result := A.Equals(B) or ((A is TAlgosimNullObject) and (B is TAlgosimNullObject));
end;

function intset(const AInts: array of TASI): TAlgosimSet;
var
  i: TASI;
begin
  Result := TAlgosimSet.Create;
  try
    for i in AInts do
      Result.AddElement(ASOInt(i));
  except
    Result.Free;
    raise;
  end;
end;

function asoset(const AElements: array of const): TAlgosimSet;
var
  i: Integer;
begin
  Result := TAlgosimSet.Create;
  try
    for i := Low(AElements) to High(AElements) do
      case AElements[i].VType of
        vtInteger:
          Result.AddElement(ASO(AElements[i].VInteger));
        vtInt64:
          Result.AddElement(ASO(AElements[i].VInt64^));
        vtBoolean:
          Result.AddElement(ASO(AElements[i].VBoolean));
        vtExtended:
          Result.AddElement(ASO(AElements[i].VExtended^));
        vtString:
          Result.AddElement(ASO(string(AElements[i].VString^)));
        vtUnicodeString:
          Result.AddElement(ASO(UnicodeString(AElements[i].VUnicodeString)));
        vtWideChar:
          Result.AddElement(ASO(AElements[i].VWideChar));
      else
        raise Exception.Create('asoset: Unsupported variant type.');
      end;
  except
    Result.Free;
    raise;
  end;
end;

function asosetex(const AElements: array of TAlgosimObject): TAlgosimSet;
var
  i: Integer;
  LastAdded: Integer;
begin
  LastAdded := -1;
  Result := TAlgosimSet.Create;
  try
    for i := Low(AElements) to High(AElements) do
    begin
      Result.AddElement(AElements[i]);
      LastAdded := i;
    end;
  except
    Result.Free;
    for i := LastAdded + 1 to High(AElements) do
      AElements[i].Free;
    raise;
  end;
end;

function asoarr(const AElements: array of const): TAlgosimArray;
var
  i: Integer;
begin
  Result := TAlgosimArray.Create;
  try
    for i := Low(AElements) to High(AElements) do
      case AElements[i].VType of
        vtInteger:
          Result.AddElement(ASO(AElements[i].VInteger));
        vtInt64:
          Result.AddElement(ASO(AElements[i].VInt64^));
        vtBoolean:
          Result.AddElement(ASO(AElements[i].VBoolean));
        vtExtended:
          Result.AddElement(ASO(AElements[i].VExtended^));
        vtString:
          Result.AddElement(ASO(string(AElements[i].VString^)));
        vtUnicodeString:
          Result.AddElement(ASO(UnicodeString(AElements[i].VUnicodeString)));
        vtWideChar:
          Result.AddElement(ASO(AElements[i].VWideChar));
      else
        raise Exception.Create('asoarr: Unsupported variant type.');
      end;
  except
    Result.Free;
    raise;
  end;
end;

function asoarrex(const AElements: array of TAlgosimObject): TAlgosimArray;
var
  i: Integer;
  LastAdded: Integer;
begin
  LastAdded := -1;
  Result := TAlgosimArray.Create;
  try
    for i := Low(AElements) to High(AElements) do
    begin
      Result.AddElement(AElements[i]);
      LastAdded := i;
    end;
  except
    Result.Free;
    for i := LastAdded + 1 to High(AElements) do
      AElements[i].Free;
    raise;
  end;
end;

function intarr(const AInts: array of TASI): TAlgosimArray;
var
  i: TASI;
begin
  Result := TAlgosimArray.Create;
  try
    for i in AInts do
      Result.AddElement(ASOInt(i));
  except
    Result.Free;
    raise;
  end;
end;

function intarrN(const AInts: array of TASI): TAlgosimArray;
var
  i: TASI;
begin
  Result := TAlgosimArray.Create;
  try
    for i in AInts do
      if i <> -1 then
        Result.AddElement(ASOInt(i))
      else
        Result.AddElement(ASO(null))
  except
    Result.Free;
    raise;
  end;
end;

function chrarr(const AChrs: array of Char): TAlgosimArray;
var
  c: Char;
begin
  Result := TAlgosimArray.Create;
  try
    for c in AChrs do
      Result.AddElement(ASO(c));
  except
    Result.Free;
    raise;
  end;
end;

function strarr(const AStrs: array of string): TAlgosimArray;
var
  s: string;
begin
  Result := TAlgosimArray.Create;
  try
    for s in AStrs do
      Result.AddElement(ASO(s));
  except
    Result.Free;
    raise;
  end;
end;

function idx2(A, B: Int64): TAlgosimArray;
begin
  Result := intarr([A, B]);
end;

function freq(AVal, AFreq: Int64): TAlgosimArray; overload;
begin
  Result := intarr([AVal, AFreq]);
end;

function freq(AVal: TASR; AFreq: Int64): TAlgosimArray; overload;
begin
  Result := asoarr([AVal, AFreq]);
end;

function freq(AVal: TASC; AFreq: Int64): TAlgosimArray; overload;
begin
  Result := asoarrex([ASO(AVal), ASOInt(AFreq)]);
end;

function freq(const AVal: string; AFreq: Int64): TAlgosimArray; overload;
begin
  Result := asoarrex([ASO(AVal), ASOInt(AFreq)]);
end;

function freq(AVal: Boolean; AFreq: Int64): TAlgosimArray; overload;
begin
  Result := asoarrex([ASO(AVal), ASOInt(AFreq)]);
end;

function freq(AVal: TAlgosimObject; AFreq: Int64): TAlgosimArray; overload;
begin
  Result := asoarrex([AVal, ASOInt(AFreq)]);
end;

var
  _hpc1, _hpc2, _hpcf: Int64;

procedure StartStopwatch;
begin
  ElapsedTime := 0.0;
  QueryPerformanceFrequency(_hpcf);
  QueryPerformanceCounter(_hpc1);
end;

procedure StopStopwatch;
begin
  QueryPerformanceCounter(_hpc2);
  ElapsedTime := (_hpc2 - _hpc1) / _hpcf;
end;


const
  SmallPrimes: array[0..999] of Integer =
    (
      2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73,
      79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163,
      167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251,
      257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
      353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
      449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557,
      563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647,
      653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757,
      761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863,
      877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983,
      991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063,
      1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163,
      1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259,
      1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361,
      1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453,
      1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549,
      1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621,
      1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
      1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847,
      1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949,
      1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039,
      2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137,
      2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251,
      2267, 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347,
      2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437,
      2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
      2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671,
      2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741,
      2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 2837, 2843,
      2851, 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, 2953, 2957,
      2963, 2969, 2971, 2999, 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067,
      3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191,
      3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307,
      3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391,
      3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517,
      3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607,
      3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701,
      3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821,
      3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919,
      3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, 4007, 4013, 4019, 4021,
      4027, 4049, 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133,
      4139, 4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243,
      4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, 4339, 4349, 4357,
      4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481,
      4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591,
      4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 4691,
      4703, 4721, 4723, 4729, 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801,
      4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937,
      4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 5021,
      5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147,
      5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273,
      5279, 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399,
      5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483,
      5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591,
      5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 5701,
      5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 5801, 5807, 5813, 5821,
      5827, 5839, 5843, 5849, 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903,
      5923, 5927, 5939, 5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053,
      6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163,
      6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271,
      6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361,
      6367, 6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 6491,
      6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619,
      6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733,
      6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841,
      6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949, 6959, 6961,
      6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, 7039, 7043, 7057,
      7069, 7079, 7103, 7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207,
      7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321,
      7331, 7333, 7349, 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477,
      7481, 7487, 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559,
      7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643, 7649, 7669,
      7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759,
      7789, 7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901,
      7907, 7919
    );

const
  JacobiSymbolValues: array[1..59] of array[1..30] of Integer =
    (
      (1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1, -1, -1,  1,  0,  1, -1, -1,  1,  0,  1, -1, -1,  1,  0,  1, -1, -1,  1,  0,  1, -1, -1,  1,  0,  1, -1, -1,  1,  0),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1,  1, -1,  1, -1, -1,  0,  1,  1, -1,  1, -1, -1,  0,  1,  1, -1,  1, -1, -1,  0,  1,  1, -1,  1, -1, -1,  0,  1,  1),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1,  1,  0,  1,  1,  0,  1,  1,  0,  1,  1,  0,  1,  1,  0,  1,  1,  0,  1,  1,  0,  1,  1,  0,  1,  1,  0,  1,  1,  0),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1, -1,  1,  1,  1, -1, -1, -1,  1, -1,  0,  1, -1,  1,  1,  1, -1, -1, -1,  1, -1,  0,  1, -1,  1,  1,  1, -1, -1, -1),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1, -1,  1,  1, -1, -1, -1, -1,  1,  1, -1,  1,  0,  1, -1,  1,  1, -1, -1, -1, -1,  1,  1, -1,  1,  0,  1, -1,  1,  1),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1,  1,  0,  1,  0,  0, -1,  1,  0,  0, -1,  0, -1, -1,  0,  1,  1,  0,  1,  0,  0, -1,  1,  0,  0, -1,  0, -1, -1,  0),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1,  1, -1,  1, -1, -1, -1,  1,  1, -1, -1, -1,  1, -1,  1,  1,  0,  1,  1, -1,  1, -1, -1, -1,  1,  1, -1, -1, -1,  1),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1, -1, -1,  1,  1,  1,  1, -1,  1, -1,  1, -1, -1, -1, -1,  1,  1, -1,  0,  1, -1, -1,  1,  1,  1,  1, -1,  1, -1,  1),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1, -1,  0,  1,  1,  0,  0, -1,  0, -1, -1,  0, -1,  0,  0,  1,  1,  0, -1,  1,  0,  1, -1,  0,  1,  1,  0,  0, -1,  0),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1,  1,  1,  1, -1,  1, -1,  1,  1, -1, -1,  1,  1, -1, -1,  1, -1,  1, -1, -1, -1, -1,  0,  1,  1,  1,  1, -1,  1, -1),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1,  1,  1,  1,  0,  1,  1,  1,  1,  0,  1,  1,  1,  1,  0,  1,  1,  1,  1,  0,  1,  1,  1,  1,  0,  1,  1,  1,  1,  0),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1, -1, -1,  1,  1,  1,  1, -1,  1, -1, -1, -1,  1, -1, -1,  1, -1, -1, -1,  1, -1,  1,  1,  1,  1, -1, -1,  1,  0,  1),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1,  1, -1,  1,  1, -1,  1,  1,  1,  1, -1, -1, -1,  1, -1,  1, -1,  1,  1,  1, -1, -1, -1, -1,  1, -1, -1,  1, -1, -1),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1,  1,  0,  1, -1,  0, -1,  1,  0, -1,  0,  0, -1, -1,  0,  1,  1,  0, -1, -1,  0,  0, -1,  0,  1, -1,  0, -1,  1,  0),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1, -1,  1,  1,  0, -1,  0, -1,  1,  0,  1,  1,  1,  0,  0,  1,  1, -1, -1,  0,  0, -1, -1, -1,  0, -1,  1,  0,  1,  0),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1, -1,  1,  1, -1, -1,  1, -1,  1,  1,  1,  1, -1, -1, -1,  1, -1, -1, -1, -1,  1, -1, -1, -1,  1,  1,  1,  1, -1,  1),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1,  1,  0,  1,  1,  0, -1,  1,  0,  1,  1,  0,  0, -1,  0,  1, -1,  0, -1,  1,  0,  1, -1,  0,  1,  0,  0, -1, -1,  0),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1,  1, -1,  1,  1, -1, -1,  1,  1,  1, -1, -1, -1, -1, -1,  1, -1,  1, -1,  1,  1, -1,  1, -1,  1, -1, -1, -1, -1, -1),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1, -1, -1,  1, -1,  1, -1, -1,  1,  1,  1, -1,  1,  1,  1,  1,  1, -1, -1, -1,  1, -1,  1,  1,  1, -1, -1, -1, -1, -1),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1, -1,  0,  1,  0,  0, -1, -1,  0,  0,  1,  0, -1,  1,  0,  1, -1,  0,  1,  0,  0, -1, -1,  0,  0,  1,  0, -1,  1,  0),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1,  1,  1,  1, -1,  1,  1,  1,  1, -1, -1,  1, -1,  1, -1,  1,  1,  1, -1, -1,  1, -1, -1,  1,  1, -1,  1,  1, -1, -1),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1,  1,  1,  1,  1,  1,  0,  1,  1,  1,  1,  1,  1,  0,  1,  1,  1,  1,  1,  1,  0,  1,  1,  1,  1,  1,  1,  0,  1,  1),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1, -1,  0,  1,  1,  0, -1, -1,  0, -1,  1,  0,  1,  1,  0,  1,  0,  0,  1,  1,  0, -1,  1,  0,  1, -1,  0, -1,  1,  0),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1, -1, -1,  1, -1,  1,  1, -1,  1,  1,  1, -1,  1, -1,  1,  1,  1, -1, -1, -1, -1, -1, -1,  1,  1, -1, -1,  1,  1, -1),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1,  1, -1,  1,  0, -1,  1,  1,  1,  0,  0, -1,  1,  1,  0,  1,  1,  1, -1,  0, -1,  0, -1, -1,  0,  1, -1,  1, -1,  0),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1,  1,  0,  1, -1,  0,  1,  1,  0, -1, -1,  0, -1,  1,  0,  1, -1,  0,  0, -1,  0, -1, -1,  0,  1, -1,  0,  1,  1,  0),
      (0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
      (1, -1,  1,  1,  1, -1,  1, -1,  1, -1, -1,  1, -1, -1,  1,  1,  1, -1,  1,  1,  1,  1, -1, -1,  1,  1,  1,  1,  1, -1)
    );

  KroneckerSymbolValues: array[1..30] of array[1..30] of TASI =
  (
    (1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1),
    (1,  0, -1,  0, -1,  0,  1,  0,  1,  0, -1,  0, -1,  0,  1,  0,  1,  0, -1,  0, -1,  0,  1,  0,  1,  0, -1,  0, -1,  0),
    (1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0),
    (1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0),
    (1, -1, -1,  1,  0,  1, -1, -1,  1,  0,  1, -1, -1,  1,  0,  1, -1, -1,  1,  0,  1, -1, -1,  1,  0,  1, -1, -1,  1,  0),
    (1,  0,  0,  0,  1,  0,  1,  0,  0,  0,  1,  0, -1,  0,  0,  0, -1,  0, -1,  0,  0,  0, -1,  0,  1,  0,  0,  0,  1,  0),
    (1,  1, -1,  1, -1, -1,  0,  1,  1, -1,  1, -1, -1,  0,  1,  1, -1,  1, -1, -1,  0,  1,  1, -1,  1, -1, -1,  0,  1,  1),
    (1,  0, -1,  0, -1,  0,  1,  0,  1,  0, -1,  0, -1,  0,  1,  0,  1,  0, -1,  0, -1,  0,  1,  0,  1,  0, -1,  0, -1,  0),
    (1,  1,  0,  1,  1,  0,  1,  1,  0,  1,  1,  0,  1,  1,  0,  1,  1,  0,  1,  1,  0,  1,  1,  0,  1,  1,  0,  1,  1,  0),
    (1,  0,  1,  0,  0,  0, -1,  0,  1,  0, -1,  0,  1,  0,  0,  0, -1,  0, -1,  0, -1,  0, -1,  0,  0,  0,  1,  0, -1,  0),
    (1, -1,  1,  1,  1, -1, -1, -1,  1, -1,  0,  1, -1,  1,  1,  1, -1, -1, -1,  1, -1,  0,  1, -1,  1,  1,  1, -1, -1, -1),
    (1,  0,  0,  0, -1,  0,  1,  0,  0,  0, -1,  0,  1,  0,  0,  0, -1,  0,  1,  0,  0,  0, -1,  0,  1,  0,  0,  0, -1,  0),
    (1, -1,  1,  1, -1, -1, -1, -1,  1,  1, -1,  1,  0,  1, -1,  1,  1, -1, -1, -1, -1,  1,  1, -1,  1,  0,  1, -1,  1,  1),
    (1,  0,  1,  0,  1,  0,  0,  0,  1,  0, -1,  0,  1,  0,  1,  0, -1,  0,  1,  0,  0,  0,  1,  0,  1,  0,  1,  0, -1,  0),
    (1,  1,  0,  1,  0,  0, -1,  1,  0,  0, -1,  0, -1, -1,  0,  1,  1,  0,  1,  0,  0, -1,  1,  0,  0, -1,  0, -1, -1,  0),
    (1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0),
    (1,  1, -1,  1, -1, -1, -1,  1,  1, -1, -1, -1,  1, -1,  1,  1,  0,  1,  1, -1,  1, -1, -1, -1,  1,  1, -1, -1, -1,  1),
    (1,  0,  0,  0, -1,  0,  1,  0,  0,  0, -1,  0, -1,  0,  0,  0,  1,  0, -1,  0,  0,  0,  1,  0,  1,  0,  0,  0, -1,  0),
    (1, -1, -1,  1,  1,  1,  1, -1,  1, -1,  1, -1, -1, -1, -1,  1,  1, -1,  0,  1, -1, -1,  1,  1,  1,  1, -1,  1, -1,  1),
    (1,  0, -1,  0,  0,  0, -1,  0,  1,  0,  1,  0, -1,  0,  0,  0, -1,  0,  1,  0,  1,  0, -1,  0,  0,  0, -1,  0,  1,  0),
    (1, -1,  0,  1,  1,  0,  0, -1,  0, -1, -1,  0, -1,  0,  0,  1,  1,  0, -1,  1,  0,  1, -1,  0,  1,  1,  0,  0, -1,  0),
    (1,  0, -1,  0, -1,  0, -1,  0,  1,  0,  0,  0,  1,  0,  1,  0, -1,  0,  1,  0,  1,  0,  1,  0,  1,  0, -1,  0,  1,  0),
    (1,  1,  1,  1, -1,  1, -1,  1,  1, -1, -1,  1,  1, -1, -1,  1, -1,  1, -1, -1, -1, -1,  0,  1,  1,  1,  1, -1,  1, -1),
    (1,  0,  0,  0,  1,  0,  1,  0,  0,  0,  1,  0, -1,  0,  0,  0, -1,  0, -1,  0,  0,  0, -1,  0,  1,  0,  0,  0,  1,  0),
    (1,  1,  1,  1,  0,  1,  1,  1,  1,  0,  1,  1,  1,  1,  0,  1,  1,  1,  1,  0,  1,  1,  1,  1,  0,  1,  1,  1,  1,  0),
    (1,  0, -1,  0,  1,  0, -1,  0,  1,  0,  1,  0,  0,  0, -1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0, -1,  0, -1,  0),
    (1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0,  1, -1,  0),
    (1,  0, -1,  0, -1,  0,  0,  0,  1,  0,  1,  0, -1,  0,  1,  0, -1,  0, -1,  0,  0,  0,  1,  0,  1,  0, -1,  0,  1,  0),
    (1, -1, -1,  1,  1,  1,  1, -1,  1, -1, -1, -1,  1, -1, -1,  1, -1, -1, -1,  1, -1,  1,  1,  1,  1, -1, -1,  1,  0,  1),
    (1,  0,  0,  0,  0,  0, -1,  0,  0,  0,  1,  0,  1,  0,  0,  0,  1,  0, -1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  1,  0)
  );

  Totients: array[1..500] of TASI =
    (
      1, 1, 2, 2, 4, 2, 6, 4, 6, 4, 10, 4, 12, 6, 8, 8, 16, 6, 18, 8, 12, 10, 22, 8, 20, 12, 18, 12, 28, 8, 30, 16, 20, 16,
      24, 12, 36, 18, 24, 16, 40, 12, 42, 20, 24, 22, 46, 16, 42, 20, 32, 24, 52, 18, 40, 24, 36, 28, 58, 16, 60, 30, 36, 32,
      48, 20, 66, 32, 44, 24, 70, 24, 72, 36, 40, 36, 60, 24, 78, 32, 54, 40, 82, 24, 64, 42, 56, 40, 88, 24, 72, 44, 60, 46,
      72, 32, 96, 42, 60, 40, 100, 32, 102, 48, 48, 52, 106, 36, 108, 40, 72, 48, 112, 36, 88, 56, 72, 58, 96, 32, 110, 60,
      80, 60, 100, 36, 126, 64, 84, 48, 130, 40, 108, 66, 72, 64, 136, 44, 138, 48, 92, 70, 120, 48, 112, 72, 84, 72, 148,
      40, 150, 72, 96, 60, 120, 48, 156, 78, 104, 64, 132, 54, 162, 80, 80, 82, 166, 48, 156, 64, 108, 84, 172, 56, 120, 80,
      116, 88, 178, 48, 180, 72, 120, 88, 144, 60, 160, 92, 108, 72, 190, 64, 192, 96, 96, 84, 196, 60, 198, 80, 132, 100,
      168, 64, 160, 102, 132, 96, 180, 48, 210, 104, 140, 106, 168, 72, 180, 108, 144, 80, 192, 72, 222, 96, 120, 112, 226,
      72, 228, 88, 120, 112, 232, 72, 184, 116, 156, 96, 238, 64, 240, 110, 162, 120, 168, 80, 216, 120, 164, 100, 250, 72,
      220, 126, 128, 128, 256, 84, 216, 96, 168, 130, 262, 80, 208, 108, 176, 132, 268, 72, 270, 128, 144, 136, 200, 88, 276,
      138, 180, 96, 280, 92, 282, 140, 144, 120, 240, 96, 272, 112, 192, 144, 292, 84, 232, 144, 180, 148, 264, 80, 252, 150,
      200, 144, 240, 96, 306, 120, 204, 120, 310, 96, 312, 156, 144, 156, 316, 104, 280, 128, 212, 132, 288, 108, 240, 162,
      216, 160, 276, 80, 330, 164, 216, 166, 264, 96, 336, 156, 224, 128, 300, 108, 294, 168, 176, 172, 346, 112, 348, 120,
      216, 160, 352, 116, 280, 176, 192, 178, 358, 96, 342, 180, 220, 144, 288, 120, 366, 176, 240, 144, 312, 120, 372, 160,
      200, 184, 336, 108, 378, 144, 252, 190, 382, 128, 240, 192, 252, 192, 388, 96, 352, 168, 260, 196, 312, 120, 396, 198,
      216, 160, 400, 132, 360, 200, 216, 168, 360, 128, 408, 160, 272, 204, 348, 132, 328, 192, 276, 180, 418, 96, 420, 210,
      276, 208, 320, 140, 360, 212, 240, 168, 430, 144, 432, 180, 224, 216, 396, 144, 438, 160, 252, 192, 442, 144, 352, 222,
      296, 192, 448, 120, 400, 224, 300, 226, 288, 144, 456, 228, 288, 176, 460, 120, 462, 224, 240, 232, 466, 144, 396, 184,
      312, 232, 420, 156, 360, 192, 312, 238, 478, 128, 432, 240, 264, 220, 384, 162, 486, 240, 324, 168, 490, 160, 448, 216,
      240, 240, 420, 164, 498, 200
    );

  Radicals: array[1..78] of TASI =
    (
      1, 2, 3, 2, 5, 6, 7, 2, 3, 10, 11, 6, 13, 14, 15, 2, 17, 6, 19, 10, 21, 22, 23, 6, 5, 26, 3, 14, 29, 30, 31, 2, 33, 34,
      35, 6, 37, 38, 39, 10, 41, 42, 43, 22, 15, 46, 47, 6, 7, 10, 51, 26, 53, 6, 55, 14, 57, 58, 59, 30, 61, 62, 21, 2, 65,
      66, 67, 34, 69, 70, 71, 6, 73, 74, 15, 38, 77, 78
    );

function IntInArray(const AValue: Integer; const AArray: array of Integer): Boolean;
var
  i: Integer;
begin
  for i := Low(AArray) to High(AArray) do
    if AArray[i] = AValue then
      Exit(True);
  Result := False;
end;

function IsSmallPrime(const AValue: Integer): Boolean;
begin
  if AValue > SmallPrimes[High(SmallPrimes)] then
    raise Exception.Create('IsSmallPrime: Prime candidate not small enough.');
  Result := IntInArray(AValue, SmallPrimes);
end;

procedure TSelfTester.TestRealMatrixQ(ALineNumber: Integer; const AFcnName: string;
  const APositives: AnsiString);
var
  c: AnsiChar;
  x: set of AnsiChar;
begin
  x := [];
  for c in RealMatrixNames do
    Include(x, c);
  for c in APositives do
  begin
    Test(ALineNumber, Format('%s(%s)', [AFcnName, c]), True);
    Exclude(x, c);
  end;
  for c in x do
    Test(ALineNumber, Format('%s(%s)', [AFcnName, c]), False);
end;

procedure TSelfTester.TestRealMatrixQImplies(ALineNumber: Integer;
  const ALeft, ARight: string);
var
  c: AnsiChar;
begin
  for c in RealMatrixNames do
    Test(ALineNumber, Format('%s(%s) ⇒ %s(%s)', [ALeft, c, ARight, c]), True);
end;

procedure AvoidDateChange;
begin
  if SecondOfTheDay(Now) > 86397 then
    Sleep(5000);
end;


{$ENDREGION}

procedure TSelfTester.TestSeq;
var
  _i, _j: Integer;
  _x: TASR;
  fn, _s, _s2: string;
  _xarr, _yarr: TArray<TASR>;
  _cxarr, _cyarr: TArray<TASC>;
  _sxarr, _syarr: TArray<string>;
  _st: TStructType;
  _bin: TArray<Byte>;
  _bm: TBitmap;
  _png: TPngImage;
//label
//  Bookmark;
begin

  Test({LINENUM}1391, 'SaveHistory(false)', null);

//  goto Bookmark;

  //
  //
  //  CHAPTER 1
  //  Literals and basic output formatting. Member access by value.
  //
  //

  Chapter('Literals, output formatting, member access by value');

  //
  // Integers
  //

  Test({LINENUM}1408, '0', 0, True, '0');
  Test({LINENUM}1409, '1', 1, True, '1');
  Test({LINENUM}1410, '2', 2, True, '2');
  Test({LINENUM}1411, '-1', -1, True, MINUS_SIGN + '1');
  Test({LINENUM}1412, HYPHEN_MINUS + '1', -1, True, MINUS_SIGN + '1');         Assert(HYPHEN_MINUS = #$2D);
  Test({LINENUM}1413, MINUS_SIGN + '1', -1, True, MINUS_SIGN + '1');           Assert(MINUS_SIGN = #$2212);
  Test({LINENUM}1414, '123', 123, True, '123');
  Test({LINENUM}1415, '-123', -123, True, MINUS_SIGN + '123');
  Test({LINENUM}1416, '123456789', 123456789, True, '123456789');
  Test({LINENUM}1417, '-123456789', -123456789, True, MINUS_SIGN + '123456789');
  Test({LINENUM}1418, '123456789123', 123456789123, True, '123456789123');
  Test({LINENUM}1419, '-123456789123', -123456789123, True, MINUS_SIGN + '123456789123');
  Test({LINENUM}1420, '123456789123456', 123456789123456, True, '123456789123456');
  Test({LINENUM}1421, '-123456789123456', -123456789123456, True, MINUS_SIGN + '123456789123456');
  Test({LINENUM}1422, '123456789123456789', 123456789123456789, True, '123456789123456789');
  Test({LINENUM}1423, '-123456789123456789', -123456789123456789, True, MINUS_SIGN + '123456789123456789');

  Test({LINENUM}1425, '10#0', 0, True, '0');
  Test({LINENUM}1426, '10#1', 1, True, '1');
  Test({LINENUM}1427, '-10#1', -1, True, MINUS_SIGN + '1');
  Test({LINENUM}1428, '10#123456', 123456, True, '123456');
  Test({LINENUM}1429, '-10#123456', -123456, True, MINUS_SIGN + '123456');

  Test({LINENUM}1431, '16#0', 0, True, '0');
  Test({LINENUM}1432, '16#1', 1, True, '1');
  Test({LINENUM}1433, '16#10', 16, True, '16');
  Test({LINENUM}1434, '16#FF', 255, True, '255');
  Test({LINENUM}1435, '-16#FF', -255, True, MINUS_SIGN + '255');
  Test({LINENUM}1436, '-16#ff', -255, True, MINUS_SIGN + '255');
  Test({LINENUM}1437, '-16#Ff', -255, True, MINUS_SIGN + '255');
  Test({LINENUM}1438, '-16#fF', -255, True, MINUS_SIGN + '255');
  Test({LINENUM}1439, '16#FFFFFFFF', 4294967295, True, '4294967295');
  Test({LINENUM}1440, '16#FFFFFFFFFFFFFFF', 1152921504606846975, True, '1152921504606846975');
  Test({LINENUM}1441, '16#fffffffffffffff', 1152921504606846975, True, '1152921504606846975');
  Test({LINENUM}1442, '16#20', 32, True, '32');
  Test({LINENUM}1443, '16#123ABCDEF', 4893429231, True, '4893429231');
  Test({LINENUM}1444, '16#A1B8EF81FA81FBA', 728332961084612538, True, '728332961084612538');
  Test({LINENUM}1445, '-16#A1B8EF81FA81FBA', -728332961084612538, True, MINUS_SIGN + '728332961084612538');
  Test({LINENUM}1446, '16#7FFFFFFFFFFFFFFF', 9223372036854775807, True, '9223372036854775807');
  Test({LINENUM}1447, '-16#7FFFFFFFFFFFFFFF', -9223372036854775807, True, MINUS_SIGN + '9223372036854775807');
  Test({LINENUM}1448, '16#8000000000000000', ESyntaxException, 'invalid numeric literal');

  Test({LINENUM}1450, '8#0', 0, True, '0');
  Test({LINENUM}1451, '8#1', 1, True, '1');
  Test({LINENUM}1452, '8#10', 8, True, '8');
  Test({LINENUM}1453, '8#11', 9, True, '9');
  Test({LINENUM}1454, '8#12', 10, True, '10');
  Test({LINENUM}1455, '8#15260', 6832, True, '6832');
  Test({LINENUM}1456, '8#4741716513576', 339557914494, True, '339557914494');
  Test({LINENUM}1457, '8#115651564324324455454', 1402087635523099436, True, '1402087635523099436');
  Test({LINENUM}1458, '-8#115651564324324455454', -1402087635523099436, True, MINUS_SIGN + '1402087635523099436');
  Test({LINENUM}1459, '8#777777777777777777777', 9223372036854775807, True, '9223372036854775807');
  Test({LINENUM}1460, '8#1000000000000000000000', ESyntaxException, 'invalid numeric literal');

  Test({LINENUM}1462, '2#0', 0, True, '0');
  Test({LINENUM}1463, '2#1', 1, True, '1');
  Test({LINENUM}1464, '2#10', 2, True, '2');
  Test({LINENUM}1465, '2#100', 4, True, '4');
  Test({LINENUM}1466, '2#1000', 8, True, '8');
  Test({LINENUM}1467, '2#10000', 16, True, '16');
  Test({LINENUM}1468, '2#100000', 32, True, '32');
  Test({LINENUM}1469, '2#1000000', 64, True, '64');
  Test({LINENUM}1470, '2#10000000', 128, True, '128');
  Test({LINENUM}1471, '2#100000000', 256, True, '256');
  Test({LINENUM}1472, '2#1000000000', 512, True, '512');
  Test({LINENUM}1473, '2#10000000000', 1024, True, '1024');
  Test({LINENUM}1474, '2#1000000000000000000000000', 16777216, True, '16777216');
  Test({LINENUM}1475, '2#100000000000000000000000000000000', 4294967296, True, '4294967296');
  Test({LINENUM}1476, '2#10000000000000000000000000000000000000000', 1099511627776, True, '1099511627776');
  Test({LINENUM}1477, '2#1011101010110110101100', 3059116, True, '3059116');
  Test({LINENUM}1478, '2#1001110101110100101010101010101', 1320834389, True, '1320834389');
  Test({LINENUM}1479, '-2#1001110101110100101010101010101', -1320834389, True, MINUS_SIGN + '1320834389');
  Test({LINENUM}1480, '2#101011110101010110101010101010101010101010110101010101010100110', 6317095989821483686, True, '6317095989821483686');
  Test({LINENUM}1481, '-2#101011110101010110101010101010101010101010110101010101010100110', -6317095989821483686, True, MINUS_SIGN + '6317095989821483686');
  Test({LINENUM}1482, '2#111111111111111111111111111111111111111111111111111111111111111', 9223372036854775807, True, '9223372036854775807');
  Test({LINENUM}1483, '2#1000000000000000000000000000000000000000000000000000000000000000', ESyntaxException, 'invalid numeric literal');

  Test({LINENUM}1485, '5#0', 0);
  Test({LINENUM}1486, '5#1', 1);
  Test({LINENUM}1487, '5#10', 5);
  Test({LINENUM}1488, '5#11', 6);
  Test({LINENUM}1489, '5#100', 25);
  Test({LINENUM}1490, '5#110', 30);
  Test({LINENUM}1491, '5#111', 31);
  Test({LINENUM}1492, '5#112', 32);
  Test({LINENUM}1493, '5#1000', 125);
  Test({LINENUM}1494, '5#123', 38);
  Test({LINENUM}1495, '5#1104332401304422434310311212', 9223372036854775807, True, '9223372036854775807');
  Test({LINENUM}1496, '5#1104332401304422434310311213', ESyntaxException, 'invalid numeric literal');

  Test({LINENUM}1498, '20#0', 0);
  Test({LINENUM}1499, '20#1', 1);
  Test({LINENUM}1500, '20#2', 2);
  Test({LINENUM}1501, '20#3', 3);
  Test({LINENUM}1502, '20#4', 4);
  Test({LINENUM}1503, '20#9', 9);
  Test({LINENUM}1504, '20#A', 10);
  Test({LINENUM}1505, '20#B', 11);
  Test({LINENUM}1506, '20#C', 12);
  Test({LINENUM}1507, '20#D', 13);
  Test({LINENUM}1508, '20#E', 14);
  Test({LINENUM}1509, '20#F', 15);
  Test({LINENUM}1510, '20#G', 16);
  Test({LINENUM}1511, '20#H', 17);
  Test({LINENUM}1512, '20#I', 18);
  Test({LINENUM}1513, '20#J', 19);
  Test({LINENUM}1514, '20#K', ESyntaxException, 'invalid base-20 digit "K" in numeric literal "20#K"');
  Test({LINENUM}1515, '20#10', 20);
  Test({LINENUM}1516, '20#11', 21);
  Test({LINENUM}1517, '20#12', 22);
  Test({LINENUM}1518, '20#123', 443);
  Test({LINENUM}1519, '20#1000', 8000);
  Test({LINENUM}1520, '20#a', 10);
  Test({LINENUM}1521, '20#b', 11);
  Test({LINENUM}1522, '20#c', 12);
  Test({LINENUM}1523, '20#5cbfjia3fh26ja7', 9223372036854775807, True, '9223372036854775807');
  Test({LINENUM}1524, '20#5cbfjia3fh26ja8', ESyntaxException, 'invalid numeric literal');

  Test({LINENUM}1526, '2#11010101010', 1706);
  Test({LINENUM}1527, '2#11010101020', ESyntaxException, 'invalid base-2 digit "2" in numeric literal "2#11010101020"');

  Test({LINENUM}1529, '10#123456', 123456);
  Test({LINENUM}1530, '10#12345A', ESyntaxException, 'invalid base-10 digit "A" in numeric literal "10#12345A"');

  Test({LINENUM}1532, '16#12345A', 1193050);
  Test({LINENUM}1533, '16#12345B', 1193051);
  Test({LINENUM}1534, '16#12345C', 1193052);
  Test({LINENUM}1535, '16#12345D', 1193053);
  Test({LINENUM}1536, '16#12345E', 1193054);
  Test({LINENUM}1537, '16#12345F', 1193055);
  Test({LINENUM}1538, '16#12345G', ESyntaxException, 'invalid base-16 digit "G" in numeric literal "16#12345G"');
  Test({LINENUM}1539, '16#123460', 1193056);
  Test({LINENUM}1540, '16#12345f', 1193055);

  Test({LINENUM}1542, '8#1234567', 342391);
  Test({LINENUM}1543, '8#1234568', ESyntaxException, 'invalid base-8 digit "8" in numeric literal "8#1234568"');
  Test({LINENUM}1544, '8#1234570', 342392);

  Test({LINENUM}1546, '36#AZ', 395);
  Test({LINENUM}1547, '36#ZZZZZ', 60466175);
  Test({LINENUM}1548, '36#az', 395);
  Test({LINENUM}1549, '36#zzzzz', 60466175);
  Test({LINENUM}1550, '36#ZzzzZ', 60466175);
  Test({LINENUM}1551, '36#1q7tyotd8hj0j', 8189181848448181891, True, '8189181848448181891');
  Test({LINENUM}1552, '-36#1q7tyotd8hj0j', -8189181848448181891, True, MINUS_SIGN + '8189181848448181891');
  Test({LINENUM}1553, '36#1y2p0ij32e8e7', 9223372036854775807, True, '9223372036854775807');
  Test({LINENUM}1554, '36#1y2p0ij32e8e8', ESyntaxException, 'invalid numeric literal');

  Test({LINENUM}1556, '1#156', ESyntaxException, 'invalid number base 1 in numeric literal "1#156"');
  Test({LINENUM}1557, '0#0', ESyntaxException, 'invalid number base 0 in numeric literal "0#0"');
  Test({LINENUM}1558, '37#123', ESyntaxException, 'invalid number base 37 in numeric literal "37#123"');
  Test({LINENUM}1559, '16#katt', ESyntaxException, 'invalid base-16 digit "k" in numeric literal "16#katt"');

  Test({LINENUM}1561, '36#0', 0, True, '0');
  Test({LINENUM}1562, '36#1', 1, True, '1');
  Test({LINENUM}1563, '36#2', 2, True, '2');
  Test({LINENUM}1564, '36#3', 3);
  Test({LINENUM}1565, '36#4', 4);
  Test({LINENUM}1566, '36#5', 5);
  Test({LINENUM}1567, '36#6', 6);
  Test({LINENUM}1568, '36#7', 7);
  Test({LINENUM}1569, '36#8', 8);
  Test({LINENUM}1570, '36#9', 9);
  Test({LINENUM}1571, '36#A', 10);
  Test({LINENUM}1572, '36#B', 11);
  Test({LINENUM}1573, '36#C', 12);
  Test({LINENUM}1574, '36#D', 13, True, '13');
  Test({LINENUM}1575, '36#E', 14);
  Test({LINENUM}1576, '36#F', 15);
  Test({LINENUM}1577, '36#G', 16);
  Test({LINENUM}1578, '36#H', 17);
  Test({LINENUM}1579, '36#I', 18);
  Test({LINENUM}1580, '36#J', 19);
  Test({LINENUM}1581, '36#K', 20);
  Test({LINENUM}1582, '36#L', 21);
  Test({LINENUM}1583, '36#M', 22);
  Test({LINENUM}1584, '36#N', 23);
  Test({LINENUM}1585, '36#O', 24, True, '24');
  Test({LINENUM}1586, '36#P', 25);
  Test({LINENUM}1587, '36#Q', 26);
  Test({LINENUM}1588, '36#R', 27);
  Test({LINENUM}1589, '36#S', 28);
  Test({LINENUM}1590, '36#T', 29);
  Test({LINENUM}1591, '36#U', 30);
  Test({LINENUM}1592, '36#V', 31);
  Test({LINENUM}1593, '36#W', 32);
  Test({LINENUM}1594, '36#X', 33);
  Test({LINENUM}1595, '36#Y', 34);
  Test({LINENUM}1596, '36#Z', 35, True, '35');
  Test({LINENUM}1597, '36#10', 36, True, '36');
  Test({LINENUM}1598, '36#11', 37, True, '37');

  Test({LINENUM}1600, '16#abc', 2748);
  Test({LINENUM}1601, '16#abc#2', ESyntaxException, 'invalid numeric literal "16#abc#2"');
  Test({LINENUM}1602, '1#2#3', ESyntaxException, 'invalid numeric literal "1#2#3"');

  // Format: number base

  Test({LINENUM}1606, '255', 255, True, '255');
  Test({LINENUM}1607, 'SetNumberBase(255, 10)', 255, True, '255');
  Test({LINENUM}1608, 'SetNumberBase(255, 16)', 255, True, 'FF');
  Test({LINENUM}1609, 'SetNumberBase(255, 2)', 255, True, '11111111');
  Test({LINENUM}1610, 'SetNumberBase(255, 3)', 255, True, '100110');
  Test({LINENUM}1611, 'SetNumberBase(30, 30)', 30, True, '10');
  Test({LINENUM}1612, 'SetNumberBase(36, 36)', 36, True, '10');
  Test({LINENUM}1613, 'SetNumberBase(2#11111111, 2)', 255, True, '11111111');
  Test({LINENUM}1614, 'SetNumberBase(2#11111111, 16)', 255, True, 'FF');

  Test({LINENUM}1616, 'SetNumberBase(255, 1)', failure, 'Invalid number base 1.');
  Test({LINENUM}1617, 'SetNumberBase(255, 37)', failure, 'Invalid number base 37.');
  Test({LINENUM}1618, 'SetNumberBase(255, 999)', failure, 'Invalid number base 999.');
  Test({LINENUM}1619, 'SetNumberBase(255, 0)', 255, True, '255');
  Test({LINENUM}1620, 'SetNumberBase(255, -1)', failure, 'A non-negative integer was expected as argument 2, but "-1" was given.');
  Test({LINENUM}1621, 'SetNumberBase(255, 2.2)', failure, 'An object of type integer was expected as argument 2, but an object of type real number was given.');
  Test({LINENUM}1622, 'SetNumberBase(255, "t")', failure, 'An object of type integer was expected as argument 2, but an object of type string was given.');
  Test({LINENUM}1623, 'SetNumberBase(255, 16, 5)', failure, 'Too many arguments.');
  Test({LINENUM}1624, 'SetNumberBase(255)', failure, 'Too few arguments. A required argument of type integer is missing.');

  Test({LINENUM}1626, '-0', 0, True, '0');
  Test({LINENUM}1627, '-255', -255, True, MINUS_SIGN + '255');
  Test({LINENUM}1628, 'SetNumberBase(-255, 0)', -255, True, MINUS_SIGN + '255');
  Test({LINENUM}1629, 'SetNumberBase(-255, 10)', -255, True, MINUS_SIGN + '255');
  Test({LINENUM}1630, 'SetNumberBase(-255, 16)', -255, True, MINUS_SIGN + 'FF');
  Test({LINENUM}1631, 'SetNumberBase(-255, 2)', -255, True, MINUS_SIGN + '11111111');
  Test({LINENUM}1632, 'SetNumberBase(-255, 3)', -255, True, MINUS_SIGN + '100110');
  Test({LINENUM}1633, 'SetNumberBase(-30, 30)', -30, True, MINUS_SIGN + '10');
  Test({LINENUM}1634, 'SetNumberBase(-36, 36)', -36, True, MINUS_SIGN + '10');
  Test({LINENUM}1635, 'SetNumberBase(-2#11111111, 2)', -255, True, MINUS_SIGN + '11111111');
  Test({LINENUM}1636, 'SetNumberBase(-2#11111111, 16)', -255, True, MINUS_SIGN + 'FF');

  Test({LINENUM}1638, 'SetNumberBase(123456789123456, 0)', 123456789123456, True, '123456789123456');
  Test({LINENUM}1639, 'SetNumberBase(123456789123456, 10)', 123456789123456, True, '123456789123456');
  Test({LINENUM}1640, 'SetNumberBase(123456789123456, 16)', 123456789123456, True, '7048860F9180');
  Test({LINENUM}1641, 'SetNumberBase(123456789123456, 8)', 123456789123456, True, '3404420603710600');
  Test({LINENUM}1642, 'SetNumberBase(123456789123456, 2)', 123456789123456, True, '11100000100100010000110000011111001000110000000');
  Test({LINENUM}1643, 'SetNumberBase(123456789123456, 3)', 123456789123456, True, '121012010100112220101001120010');
  Test({LINENUM}1644, 'SetNumberBase(123456789123456, 32)', 123456789123456, True, '3G9230V4C0');
  Test({LINENUM}1645, 'SetNumberBase(123456789123456, 36)', 123456789123456, True, '17RF9KOMTC');

  Test({LINENUM}1647, 'SetNumberBase(-123456789123456, 0)', -123456789123456, True, MINUS_SIGN + '123456789123456');
  Test({LINENUM}1648, 'SetNumberBase(-123456789123456, 10)', -123456789123456, True, MINUS_SIGN + '123456789123456');
  Test({LINENUM}1649, 'SetNumberBase(-123456789123456, 16)', -123456789123456, True, MINUS_SIGN + '7048860F9180');
  Test({LINENUM}1650, 'SetNumberBase(-123456789123456, 8)', -123456789123456, True, MINUS_SIGN + '3404420603710600');
  Test({LINENUM}1651, 'SetNumberBase(-123456789123456, 2)', -123456789123456, True, MINUS_SIGN + '11100000100100010000110000011111001000110000000');
  Test({LINENUM}1652, 'SetNumberBase(-123456789123456, 3)', -123456789123456, True, MINUS_SIGN + '121012010100112220101001120010');
  Test({LINENUM}1653, 'SetNumberBase(-123456789123456, 32)', -123456789123456, True, MINUS_SIGN + '3G9230V4C0');
  Test({LINENUM}1654, 'SetNumberBase(-123456789123456, 36)', -123456789123456, True, MINUS_SIGN + '17RF9KOMTC');

  Test({LINENUM}1656, 'SetNumberBase(123456789123456789, 0)', 123456789123456789, True, '123456789123456789');
  Test({LINENUM}1657, 'SetNumberBase(123456789123456789, 10)', 123456789123456789, True, '123456789123456789');
  Test({LINENUM}1658, 'SetNumberBase(123456789123456789, 16)', 123456789123456789, True, '1B69B4BACD05F15');
  Test({LINENUM}1659, 'SetNumberBase(123456789123456789, 8)', 123456789123456789, True, '6664664565464057425');
  Test({LINENUM}1660, 'SetNumberBase(123456789123456789, 2)', 123456789123456789, True, '110110110100110110100101110101100110100000101111100010101');
  Test({LINENUM}1661, 'SetNumberBase(123456789123456789, 3)', 123456789123456789, True, '211012121210012202221200111210202100');
  Test({LINENUM}1662, 'SetNumberBase(8482137697523097365, 2)', 8482137697523097365, True, '111010110110110100110110100101110101100110100000101111100010101');

  Test({LINENUM}1664, 'SetNumberBase(-123456789123456789, 0)', -123456789123456789, True, MINUS_SIGN + '123456789123456789');
  Test({LINENUM}1665, 'SetNumberBase(-123456789123456789, 10)', -123456789123456789, True, MINUS_SIGN + '123456789123456789');
  Test({LINENUM}1666, 'SetNumberBase(-123456789123456789, 16)', -123456789123456789, True, MINUS_SIGN + '1B69B4BACD05F15');
  Test({LINENUM}1667, 'SetNumberBase(-123456789123456789, 8)', -123456789123456789, True, MINUS_SIGN + '6664664565464057425');
  Test({LINENUM}1668, 'SetNumberBase(-123456789123456789, 2)', -123456789123456789, True, MINUS_SIGN + '110110110100110110100101110101100110100000101111100010101');
  Test({LINENUM}1669, 'SetNumberBase(-123456789123456789, 3)', -123456789123456789, True, MINUS_SIGN + '211012121210012202221200111210202100');
  Test({LINENUM}1670, 'SetNumberBase(-8482137697523097365, 2)', -8482137697523097365, True, MINUS_SIGN + '111010110110110100110110100101110101100110100000101111100010101');

  Test({LINENUM}1672, 'SetNumberBase(0, 0)', 0, True, '0');
  Test({LINENUM}1673, 'SetNumberBase(0, 2)', 0, True, '0');
  Test({LINENUM}1674, 'SetNumberBase(0, 5)', 0, True, '0');
  Test({LINENUM}1675, 'SetNumberBase(0, 8)', 0, True, '0');
  Test({LINENUM}1676, 'SetNumberBase(0, 10)', 0, True, '0');
  Test({LINENUM}1677, 'SetNumberBase(0, 16)', 0, True, '0');
  Test({LINENUM}1678, 'SetNumberBase(0, 36)', 0, True, '0');

  Test({LINENUM}1680, 'SetNumberBase(1, 0)', 1, True, '1');
  Test({LINENUM}1681, 'SetNumberBase(1, 2)', 1, True, '1');
  Test({LINENUM}1682, 'SetNumberBase(1, 5)', 1, True, '1');
  Test({LINENUM}1683, 'SetNumberBase(1, 8)', 1, True, '1');
  Test({LINENUM}1684, 'SetNumberBase(1, 10)', 1, True, '1');
  Test({LINENUM}1685, 'SetNumberBase(1, 16)', 1, True, '1');
  Test({LINENUM}1686, 'SetNumberBase(1, 36)', 1, True, '1');

  Test({LINENUM}1688, 'SetNumberBase(2, 0)', 2, True, '2');
  Test({LINENUM}1689, 'SetNumberBase(2, 2)', 2, True, '10');
  Test({LINENUM}1690, 'SetNumberBase(2, 5)', 2, True, '2');
  Test({LINENUM}1691, 'SetNumberBase(2, 8)', 2, True, '2');
  Test({LINENUM}1692, 'SetNumberBase(2, 10)', 2, True, '2');
  Test({LINENUM}1693, 'SetNumberBase(2, 16)', 2, True, '2');
  Test({LINENUM}1694, 'SetNumberBase(2, 36)', 2, True, '2');

  Test({LINENUM}1696, 'SetNumberBase(-2, 0)', -2, True, MINUS_SIGN + '2');
  Test({LINENUM}1697, 'SetNumberBase(-2, 2)', -2, True, MINUS_SIGN + '10');
  Test({LINENUM}1698, 'SetNumberBase(-2, 5)', -2, True, MINUS_SIGN + '2');
  Test({LINENUM}1699, 'SetNumberBase(-2, 8)', -2, True, MINUS_SIGN + '2');
  Test({LINENUM}1700, 'SetNumberBase(-2, 10)', -2, True, MINUS_SIGN + '2');
  Test({LINENUM}1701, 'SetNumberBase(-2, 16)', -2, True, MINUS_SIGN + '2');
  Test({LINENUM}1702, 'SetNumberBase(-2, 36)', -2, True, MINUS_SIGN + '2');

  Test({LINENUM}1704, 'SetNumberBase(2, 2)', 2, True, '10');
  Test({LINENUM}1705, 'SetNumberBase(3, 3)', 3, True, '10');
  Test({LINENUM}1706, 'SetNumberBase(4, 4)', 4, True, '10');
  Test({LINENUM}1707, 'SetNumberBase(5, 5)', 5, True, '10');
  Test({LINENUM}1708, 'SetNumberBase(6, 6)', 6, True, '10');
  Test({LINENUM}1709, 'SetNumberBase(7, 7)', 7, True, '10');
  Test({LINENUM}1710, 'SetNumberBase(8, 8)', 8, True, '10');
  Test({LINENUM}1711, 'SetNumberBase(9, 9)', 9, True, '10');
  Test({LINENUM}1712, 'SetNumberBase(10, 10)', 10, True, '10');
  Test({LINENUM}1713, 'SetNumberBase(11, 11)', 11, True, '10');

  Test({LINENUM}1715, 'SetNumberBase(0, 36)', 0, True, '0');
  Test({LINENUM}1716, 'SetNumberBase(1, 36)', 1, True, '1');
  Test({LINENUM}1717, 'SetNumberBase(2, 36)', 2, True, '2');
  Test({LINENUM}1718, 'SetNumberBase(3, 36)', 3, True, '3');
  Test({LINENUM}1719, 'SetNumberBase(4, 36)', 4, True, '4');
  Test({LINENUM}1720, 'SetNumberBase(5, 36)', 5, True, '5');
  Test({LINENUM}1721, 'SetNumberBase(6, 36)', 6, True, '6');
  Test({LINENUM}1722, 'SetNumberBase(7, 36)', 7, True, '7');
  Test({LINENUM}1723, 'SetNumberBase(8, 36)', 8, True, '8');
  Test({LINENUM}1724, 'SetNumberBase(9, 36)', 9, True, '9');
  Test({LINENUM}1725, 'SetNumberBase(10, 36)', 10, True, 'A');
  Test({LINENUM}1726, 'SetNumberBase(11, 36)', 11, True, 'B');
  Test({LINENUM}1727, 'SetNumberBase(12, 36)', 12, True, 'C');
  Test({LINENUM}1728, 'SetNumberBase(13, 36)', 13, True, 'D');
  Test({LINENUM}1729, 'SetNumberBase(14, 36)', 14, True, 'E');
  Test({LINENUM}1730, 'SetNumberBase(15, 36)', 15, True, 'F');
  Test({LINENUM}1731, 'SetNumberBase(16, 36)', 16, True, 'G');
  Test({LINENUM}1732, 'SetNumberBase(17, 36)', 17, True, 'H');
  Test({LINENUM}1733, 'SetNumberBase(18, 36)', 18, True, 'I');
  Test({LINENUM}1734, 'SetNumberBase(19, 36)', 19, True, 'J');
  Test({LINENUM}1735, 'SetNumberBase(20, 36)', 20, True, 'K');
  Test({LINENUM}1736, 'SetNumberBase(21, 36)', 21, True, 'L');
  Test({LINENUM}1737, 'SetNumberBase(22, 36)', 22, True, 'M');
  Test({LINENUM}1738, 'SetNumberBase(23, 36)', 23, True, 'N');
  Test({LINENUM}1739, 'SetNumberBase(24, 36)', 24, True, 'O');
  Test({LINENUM}1740, 'SetNumberBase(25, 36)', 25, True, 'P');
  Test({LINENUM}1741, 'SetNumberBase(26, 36)', 26, True, 'Q');
  Test({LINENUM}1742, 'SetNumberBase(27, 36)', 27, True, 'R');
  Test({LINENUM}1743, 'SetNumberBase(28, 36)', 28, True, 'S');
  Test({LINENUM}1744, 'SetNumberBase(29, 36)', 29, True, 'T');
  Test({LINENUM}1745, 'SetNumberBase(30, 36)', 30, True, 'U');
  Test({LINENUM}1746, 'SetNumberBase(31, 36)', 31, True, 'V');
  Test({LINENUM}1747, 'SetNumberBase(32, 36)', 32, True, 'W');
  Test({LINENUM}1748, 'SetNumberBase(33, 36)', 33, True, 'X');
  Test({LINENUM}1749, 'SetNumberBase(34, 36)', 34, True, 'Y');
  Test({LINENUM}1750, 'SetNumberBase(35, 36)', 35, True, 'Z');
  Test({LINENUM}1751, 'SetNumberBase(36, 36)', 36, True, '10');
  Test({LINENUM}1752, 'SetNumberBase(37, 36)', 37, True, '11');

  Test({LINENUM}1754, 'SetNumberBase(856324759261834725, 2)', 856324759261834725, True, '101111100010010001101101010011100000001011000110110111100101');
  Test({LINENUM}1755, 'SetNumberBase(856324759261834725, 3)', 856324759261834725, True, '12201001010002100111010102020021220020');
  Test({LINENUM}1756, 'SetNumberBase(856324759261834725, 4)', 856324759261834725, True, '233202101231103200023012313211');
  Test({LINENUM}1757, 'SetNumberBase(856324759261834725, 5)', 856324759261834725, True, '24140410144323432012202400');
  Test({LINENUM}1758, 'SetNumberBase(856324759261834725, 6)', 856324759261834725, True, '103011414431331422425353');
  Test({LINENUM}1759, 'SetNumberBase(856324759261834725, 7)', 856324759261834725, True, '1350602331133464501312');
  Test({LINENUM}1760, 'SetNumberBase(856324759261834725, 8)', 856324759261834725, True, '57422155234013066745');
  Test({LINENUM}1761, 'SetNumberBase(856324759261834725, 16)', 856324759261834725, True, 'BE246D4E02C6DE5');
  Test({LINENUM}1762, 'SetNumberBase(856324759261834725, 32)', 856324759261834725, True, 'NOI6QJG2ORF5');
  Test({LINENUM}1763, 'SetNumberBase(856324759261834725, 36)', 856324759261834725, True, '6I7PSJLAEQXX');

  Test({LINENUM}1765, 'SetNumberBase(-856324759261834725, 2)', -856324759261834725, True, MINUS_SIGN + '101111100010010001101101010011100000001011000110110111100101');
  Test({LINENUM}1766, 'SetNumberBase(-856324759261834725, 3)', -856324759261834725, True, MINUS_SIGN + '12201001010002100111010102020021220020');
  Test({LINENUM}1767, 'SetNumberBase(-856324759261834725, 4)', -856324759261834725, True, MINUS_SIGN + '233202101231103200023012313211');
  Test({LINENUM}1768, 'SetNumberBase(-856324759261834725, 5)', -856324759261834725, True, MINUS_SIGN + '24140410144323432012202400');
  Test({LINENUM}1769, 'SetNumberBase(-856324759261834725, 6)', -856324759261834725, True, MINUS_SIGN + '103011414431331422425353');
  Test({LINENUM}1770, 'SetNumberBase(-856324759261834725, 7)', -856324759261834725, True, MINUS_SIGN + '1350602331133464501312');
  Test({LINENUM}1771, 'SetNumberBase(-856324759261834725, 8)', -856324759261834725, True, MINUS_SIGN + '57422155234013066745');
  Test({LINENUM}1772, 'SetNumberBase(-856324759261834725, 16)', -856324759261834725, True, MINUS_SIGN + 'BE246D4E02C6DE5');
  Test({LINENUM}1773, 'SetNumberBase(-856324759261834725, 32)', -856324759261834725, True, MINUS_SIGN + 'NOI6QJG2ORF5');
  Test({LINENUM}1774, 'SetNumberBase(-856324759261834725, 36)', -856324759261834725, True, MINUS_SIGN + '6I7PSJLAEQXX');

  Test({LINENUM}1776, 'SetNumberBase(9223372036854775807, 0)', 9223372036854775807, True, '9223372036854775807');
  Test({LINENUM}1777, 'SetNumberBase(9223372036854775807, 10)', 9223372036854775807, True, '9223372036854775807');
  Test({LINENUM}1778, 'SetNumberBase(9223372036854775807, 2)', 9223372036854775807, True, '111111111111111111111111111111111111111111111111111111111111111');
  Test({LINENUM}1779, 'SetNumberBase(9223372036854775807, 8)', 9223372036854775807, True, '777777777777777777777');
  Test({LINENUM}1780, 'SetNumberBase(9223372036854775807, 16)', 9223372036854775807, True, '7FFFFFFFFFFFFFFF');
  Test({LINENUM}1781, 'SetNumberBase(9223372036854775807, 36)', 9223372036854775807, True, '1Y2P0IJ32E8E7');

  // Format: Minimum length

  Test({LINENUM}1785, 'SetMinLength(123, 0)', 123, True, '123');
  Test({LINENUM}1786, 'SetMinLength(123, 1)', 123, True, '123');
  Test({LINENUM}1787, 'SetMinLength(123, 2)', 123, True, '123');
  Test({LINENUM}1788, 'SetMinLength(123, 3)', 123, True, '123');
  Test({LINENUM}1789, 'SetMinLength(123, 4)', 123, True, '0123');
  Test({LINENUM}1790, 'SetMinLength(123, 5)', 123, True, '00123');
  Test({LINENUM}1791, 'SetMinLength(123, 6)', 123, True, '000123');
  Test({LINENUM}1792, 'SetMinLength(123, 7)', 123, True, '0000123');
  Test({LINENUM}1793, 'SetMinLength(123, 8)', 123, True, '00000123');
  Test({LINENUM}1794, 'SetMinLength(123, 9)', 123, True, '000000123');
  Test({LINENUM}1795, 'SetMinLength(123, 10)', 123, True, '0000000123');
  Test({LINENUM}1796, 'SetMinLength(123, 11)', 123, True, '00000000123');
  Test({LINENUM}1797, 'SetMinLength(123, 12)', 123, True, '000000000123');
  Test({LINENUM}1798, 'SetMinLength(123, 13)', 123, True, '0000000000123');
  Test({LINENUM}1799, 'SetMinLength(123, 14)', 123, True, '00000000000123');
  Test({LINENUM}1800, 'SetMinLength(123, 15)', 123, True, '000000000000123');
  Test({LINENUM}1801, 'SetMinLength(123, 16)', 123, True, '0000000000000123');
  Test({LINENUM}1802, 'SetMinLength(123, 17)', 123, True, '00000000000000123');
  Test({LINENUM}1803, 'SetMinLength(123, 18)', 123, True, '000000000000000123');
  Test({LINENUM}1804, 'SetMinLength(123, 19)', 123, True, '0000000000000000123');
  Test({LINENUM}1805, 'SetMinLength(123, 20)', 123, True, '00000000000000000123');

  Test({LINENUM}1807, 'SetMinLength(-123, 0)', -123, True, MINUS_SIGN + '123');
  Test({LINENUM}1808, 'SetMinLength(-123, 1)', -123, True, MINUS_SIGN + '123');
  Test({LINENUM}1809, 'SetMinLength(-123, 2)', -123, True, MINUS_SIGN + '123');
  Test({LINENUM}1810, 'SetMinLength(-123, 3)', -123, True, MINUS_SIGN + '123');
  Test({LINENUM}1811, 'SetMinLength(-123, 4)', -123, True, MINUS_SIGN + '0123');
  Test({LINENUM}1812, 'SetMinLength(-123, 5)', -123, True, MINUS_SIGN + '00123');
  Test({LINENUM}1813, 'SetMinLength(-123, 6)', -123, True, MINUS_SIGN + '000123');
  Test({LINENUM}1814, 'SetMinLength(-123, 7)', -123, True, MINUS_SIGN + '0000123');
  Test({LINENUM}1815, 'SetMinLength(-123, 8)', -123, True, MINUS_SIGN + '00000123');
  Test({LINENUM}1816, 'SetMinLength(-123, 9)', -123, True, MINUS_SIGN + '000000123');
  Test({LINENUM}1817, 'SetMinLength(-123, 10)', -123, True, MINUS_SIGN + '0000000123');
  Test({LINENUM}1818, 'SetMinLength(-123, 11)', -123, True, MINUS_SIGN + '00000000123');
  Test({LINENUM}1819, 'SetMinLength(-123, 12)', -123, True, MINUS_SIGN + '000000000123');
  Test({LINENUM}1820, 'SetMinLength(-123, 13)', -123, True, MINUS_SIGN + '0000000000123');
  Test({LINENUM}1821, 'SetMinLength(-123, 14)', -123, True, MINUS_SIGN + '00000000000123');
  Test({LINENUM}1822, 'SetMinLength(-123, 15)', -123, True, MINUS_SIGN + '000000000000123');
  Test({LINENUM}1823, 'SetMinLength(-123, 16)', -123, True, MINUS_SIGN + '0000000000000123');
  Test({LINENUM}1824, 'SetMinLength(-123, 17)', -123, True, MINUS_SIGN + '00000000000000123');
  Test({LINENUM}1825, 'SetMinLength(-123, 18)', -123, True, MINUS_SIGN + '000000000000000123');
  Test({LINENUM}1826, 'SetMinLength(-123, 19)', -123, True, MINUS_SIGN + '0000000000000000123');
  Test({LINENUM}1827, 'SetMinLength(-123, 20)', -123, True, MINUS_SIGN + '00000000000000000123');

  Test({LINENUM}1829, 'SetMinLength(123, 100)', 123, True, '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000123');
  Test({LINENUM}1830, 'SetMinLength(-123, 100)', -123, True, MINUS_SIGN + '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000123');

  Test({LINENUM}1832, 'SetMinLength(0, 0)', 0, True, '0');
  Test({LINENUM}1833, 'SetMinLength(0, 1)', 0, True, '0');
  Test({LINENUM}1834, 'SetMinLength(0, 2)', 0, True, '00');
  Test({LINENUM}1835, 'SetMinLength(0, 3)', 0, True, '000');
  Test({LINENUM}1836, 'SetMinLength(0, 4)', 0, True, '0000');
  Test({LINENUM}1837, 'SetMinLength(0, 5)', 0, True, '00000');
  Test({LINENUM}1838, 'SetMinLength(0, 6)', 0, True, '000000');
  Test({LINENUM}1839, 'SetMinLength(0, 20)', 0, True, '00000000000000000000');
  Test({LINENUM}1840, 'SetMinLength(0, 100)', 0, True, '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000');

  Test({LINENUM}1842, 'SetMinLength(-0, 0)', 0, True, '0');
  Test({LINENUM}1843, 'SetMinLength(-0, 1)', 0, True, '0');
  Test({LINENUM}1844, 'SetMinLength(-0, 2)', 0, True, '00');
  Test({LINENUM}1845, 'SetMinLength(-0, 3)', 0, True, '000');
  Test({LINENUM}1846, 'SetMinLength(-0, 4)', 0, True, '0000');
  Test({LINENUM}1847, 'SetMinLength(-0, 5)', 0, True, '00000');
  Test({LINENUM}1848, 'SetMinLength(-0, 6)', 0, True, '000000');
  Test({LINENUM}1849, 'SetMinLength(-0, 20)', 0, True, '00000000000000000000');
  Test({LINENUM}1850, 'SetMinLength(-0, 100)', 0, True, '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000');

  Test({LINENUM}1852, 'SetMinLength(123456789123456789, 0)', 123456789123456789, True, '123456789123456789');
  Test({LINENUM}1853, 'SetMinLength(123456789123456789, 1)', 123456789123456789, True, '123456789123456789');
  Test({LINENUM}1854, 'SetMinLength(123456789123456789, 2)', 123456789123456789, True, '123456789123456789');
  Test({LINENUM}1855, 'SetMinLength(123456789123456789, 3)', 123456789123456789, True, '123456789123456789');
  Test({LINENUM}1856, 'SetMinLength(123456789123456789, 4)', 123456789123456789, True, '123456789123456789');
  Test({LINENUM}1857, 'SetMinLength(123456789123456789, 5)', 123456789123456789, True, '123456789123456789');
  Test({LINENUM}1858, 'SetMinLength(123456789123456789, 6)', 123456789123456789, True, '123456789123456789');
  Test({LINENUM}1859, 'SetMinLength(123456789123456789, 7)', 123456789123456789, True, '123456789123456789');
  Test({LINENUM}1860, 'SetMinLength(123456789123456789, 8)', 123456789123456789, True, '123456789123456789');
  Test({LINENUM}1861, 'SetMinLength(123456789123456789, 9)', 123456789123456789, True, '123456789123456789');
  Test({LINENUM}1862, 'SetMinLength(123456789123456789, 10)', 123456789123456789, True, '123456789123456789');
  Test({LINENUM}1863, 'SetMinLength(123456789123456789, 11)', 123456789123456789, True, '123456789123456789');
  Test({LINENUM}1864, 'SetMinLength(123456789123456789, 12)', 123456789123456789, True, '123456789123456789');
  Test({LINENUM}1865, 'SetMinLength(123456789123456789, 13)', 123456789123456789, True, '123456789123456789');
  Test({LINENUM}1866, 'SetMinLength(123456789123456789, 14)', 123456789123456789, True, '123456789123456789');
  Test({LINENUM}1867, 'SetMinLength(123456789123456789, 15)', 123456789123456789, True, '123456789123456789');
  Test({LINENUM}1868, 'SetMinLength(123456789123456789, 16)', 123456789123456789, True, '123456789123456789');
  Test({LINENUM}1869, 'SetMinLength(123456789123456789, 17)', 123456789123456789, True, '123456789123456789');
  Test({LINENUM}1870, 'SetMinLength(123456789123456789, 18)', 123456789123456789, True, '123456789123456789');
  Test({LINENUM}1871, 'SetMinLength(123456789123456789, 19)', 123456789123456789, True, '0123456789123456789');
  Test({LINENUM}1872, 'SetMinLength(123456789123456789, 20)', 123456789123456789, True, '00123456789123456789');
  Test({LINENUM}1873, 'SetMinLength(123456789123456789, 21)', 123456789123456789, True, '000123456789123456789');
  Test({LINENUM}1874, 'SetMinLength(123456789123456789, 22)', 123456789123456789, True, '0000123456789123456789');
  Test({LINENUM}1875, 'SetMinLength(123456789123456789, 100)', 123456789123456789, True, '0000000000000000000000000000000000000000000000000000000000000000000000000000000000123456789123456789');

  Test({LINENUM}1877, 'SetMinLength(-123456789123456789, 0)', -123456789123456789, True, MINUS_SIGN + '123456789123456789');
  Test({LINENUM}1878, 'SetMinLength(-123456789123456789, 1)', -123456789123456789, True, MINUS_SIGN + '123456789123456789');
  Test({LINENUM}1879, 'SetMinLength(-123456789123456789, 2)', -123456789123456789, True, MINUS_SIGN + '123456789123456789');
  Test({LINENUM}1880, 'SetMinLength(-123456789123456789, 3)', -123456789123456789, True, MINUS_SIGN + '123456789123456789');
  Test({LINENUM}1881, 'SetMinLength(-123456789123456789, 4)', -123456789123456789, True, MINUS_SIGN + '123456789123456789');
  Test({LINENUM}1882, 'SetMinLength(-123456789123456789, 5)', -123456789123456789, True, MINUS_SIGN + '123456789123456789');
  Test({LINENUM}1883, 'SetMinLength(-123456789123456789, 6)', -123456789123456789, True, MINUS_SIGN + '123456789123456789');
  Test({LINENUM}1884, 'SetMinLength(-123456789123456789, 7)', -123456789123456789, True, MINUS_SIGN + '123456789123456789');
  Test({LINENUM}1885, 'SetMinLength(-123456789123456789, 8)', -123456789123456789, True, MINUS_SIGN + '123456789123456789');
  Test({LINENUM}1886, 'SetMinLength(-123456789123456789, 9)', -123456789123456789, True, MINUS_SIGN + '123456789123456789');
  Test({LINENUM}1887, 'SetMinLength(-123456789123456789, 10)', -123456789123456789, True, MINUS_SIGN + '123456789123456789');
  Test({LINENUM}1888, 'SetMinLength(-123456789123456789, 11)', -123456789123456789, True, MINUS_SIGN + '123456789123456789');
  Test({LINENUM}1889, 'SetMinLength(-123456789123456789, 12)', -123456789123456789, True, MINUS_SIGN + '123456789123456789');
  Test({LINENUM}1890, 'SetMinLength(-123456789123456789, 13)', -123456789123456789, True, MINUS_SIGN + '123456789123456789');
  Test({LINENUM}1891, 'SetMinLength(-123456789123456789, 14)', -123456789123456789, True, MINUS_SIGN + '123456789123456789');
  Test({LINENUM}1892, 'SetMinLength(-123456789123456789, 15)', -123456789123456789, True, MINUS_SIGN + '123456789123456789');
  Test({LINENUM}1893, 'SetMinLength(-123456789123456789, 16)', -123456789123456789, True, MINUS_SIGN + '123456789123456789');
  Test({LINENUM}1894, 'SetMinLength(-123456789123456789, 17)', -123456789123456789, True, MINUS_SIGN + '123456789123456789');
  Test({LINENUM}1895, 'SetMinLength(-123456789123456789, 18)', -123456789123456789, True, MINUS_SIGN + '123456789123456789');
  Test({LINENUM}1896, 'SetMinLength(-123456789123456789, 19)', -123456789123456789, True, MINUS_SIGN + '0123456789123456789');
  Test({LINENUM}1897, 'SetMinLength(-123456789123456789, 20)', -123456789123456789, True, MINUS_SIGN + '00123456789123456789');
  Test({LINENUM}1898, 'SetMinLength(-123456789123456789, 21)', -123456789123456789, True, MINUS_SIGN + '000123456789123456789');
  Test({LINENUM}1899, 'SetMinLength(-123456789123456789, 22)', -123456789123456789, True, MINUS_SIGN + '0000123456789123456789');
  Test({LINENUM}1900, 'SetMinLength(-123456789123456789, 100)', -123456789123456789, True, MINUS_SIGN + '0000000000000000000000000000000000000000000000000000000000000000000000000000000000123456789123456789');

  Test({LINENUM}1902, 'SetMinLength(123, 255)', 123, True, StringOfChar('0', 252) + '123');
  Test({LINENUM}1903, 'SetMinLength(123, 256)', failure, 'Invalid minimum length 256.');
  Test({LINENUM}1904, 'SetMinLength(123, -1)', failure, 'A non-negative integer was expected as argument 2, but "-1" was given.');
  Test({LINENUM}1905, 'SetMinLength(123, 7.6)', failure, 'An object of type integer was expected as argument 2, but an object of type real number was given.');
  Test({LINENUM}1906, 'SetMinLength(123, "h")', failure, 'An object of type integer was expected as argument 2, but an object of type string was given.');
  Test({LINENUM}1907, 'SetMinLength(123, 10, 20)', failure, 'Too many arguments.');
  Test({LINENUM}1908, 'SetMinLength(123)', failure, 'Too few arguments. A required argument of type integer is missing.');

  // Format: number base + minimum length

  Test({LINENUM}1912, 'SetMinLength(SetNumberBase(255, 10), 0)', 255, True, '255');
  Test({LINENUM}1913, 'SetMinLength(SetNumberBase(255, 10), 1)', 255, True, '255');
  Test({LINENUM}1914, 'SetMinLength(SetNumberBase(255, 10), 2)', 255, True, '255');
  Test({LINENUM}1915, 'SetMinLength(SetNumberBase(255, 10), 3)', 255, True, '255');
  Test({LINENUM}1916, 'SetMinLength(SetNumberBase(255, 10), 4)', 255, True, '0255');
  Test({LINENUM}1917, 'SetMinLength(SetNumberBase(255, 10), 8)', 255, True, '00000255');
  Test({LINENUM}1918, 'SetMinLength(SetNumberBase(255, 10), 16)', 255, True, '0000000000000255');
  Test({LINENUM}1919, 'SetMinLength(SetNumberBase(255, 10), 100)', 255, True, '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000255');

  Test({LINENUM}1921, 'SetMinLength(SetNumberBase(-255, 10), 0)', -255, True, MINUS_SIGN + '255');
  Test({LINENUM}1922, 'SetMinLength(SetNumberBase(-255, 10), 1)', -255, True, MINUS_SIGN + '255');
  Test({LINENUM}1923, 'SetMinLength(SetNumberBase(-255, 10), 2)', -255, True, MINUS_SIGN + '255');
  Test({LINENUM}1924, 'SetMinLength(SetNumberBase(-255, 10), 3)', -255, True, MINUS_SIGN + '255');
  Test({LINENUM}1925, 'SetMinLength(SetNumberBase(-255, 10), 4)', -255, True, MINUS_SIGN + '0255');
  Test({LINENUM}1926, 'SetMinLength(SetNumberBase(-255, 10), 8)', -255, True, MINUS_SIGN + '00000255');
  Test({LINENUM}1927, 'SetMinLength(SetNumberBase(-255, 10), 16)', -255, True, MINUS_SIGN + '0000000000000255');
  Test({LINENUM}1928, 'SetMinLength(SetNumberBase(-255, 10), 100)', -255, True, MINUS_SIGN + '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000255');

  Test({LINENUM}1930, 'SetMinLength(SetNumberBase(0, 10), 0)', 0, True, '0');
  Test({LINENUM}1931, 'SetMinLength(SetNumberBase(0, 10), 1)', 0, True, '0');
  Test({LINENUM}1932, 'SetMinLength(SetNumberBase(0, 10), 2)', 0, True, '00');
  Test({LINENUM}1933, 'SetMinLength(SetNumberBase(0, 10), 8)', 0, True, '00000000');
  Test({LINENUM}1934, 'SetMinLength(SetNumberBase(0, 10), 100)', 0, True, '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000');

  Test({LINENUM}1936, 'SetMinLength(SetNumberBase(255, 16), 0)', 255, True, 'FF');
  Test({LINENUM}1937, 'SetMinLength(SetNumberBase(255, 16), 1)', 255, True, 'FF');
  Test({LINENUM}1938, 'SetMinLength(SetNumberBase(255, 16), 2)', 255, True, 'FF');
  Test({LINENUM}1939, 'SetMinLength(SetNumberBase(255, 16), 3)', 255, True, '0FF');
  Test({LINENUM}1940, 'SetMinLength(SetNumberBase(255, 16), 4)', 255, True, '00FF');
  Test({LINENUM}1941, 'SetMinLength(SetNumberBase(255, 16), 8)', 255, True, '000000FF');
  Test({LINENUM}1942, 'SetMinLength(SetNumberBase(255, 16), 16)', 255, True, '00000000000000FF');
  Test({LINENUM}1943, 'SetMinLength(SetNumberBase(255, 16), 100)', 255, True, '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF');

  Test({LINENUM}1945, 'SetMinLength(SetNumberBase(-255, 16), 0)', -255, True, MINUS_SIGN + 'FF');
  Test({LINENUM}1946, 'SetMinLength(SetNumberBase(-255, 16), 1)', -255, True, MINUS_SIGN + 'FF');
  Test({LINENUM}1947, 'SetMinLength(SetNumberBase(-255, 16), 2)', -255, True, MINUS_SIGN + 'FF');
  Test({LINENUM}1948, 'SetMinLength(SetNumberBase(-255, 16), 3)', -255, True, MINUS_SIGN + '0FF');
  Test({LINENUM}1949, 'SetMinLength(SetNumberBase(-255, 16), 4)', -255, True, MINUS_SIGN + '00FF');
  Test({LINENUM}1950, 'SetMinLength(SetNumberBase(-255, 16), 8)', -255, True, MINUS_SIGN + '000000FF');
  Test({LINENUM}1951, 'SetMinLength(SetNumberBase(-255, 16), 16)', -255, True, MINUS_SIGN + '00000000000000FF');
  Test({LINENUM}1952, 'SetMinLength(SetNumberBase(-255, 16), 100)', -255, True, MINUS_SIGN + '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF');

  Test({LINENUM}1954, 'SetMinLength(SetNumberBase(0, 16), 0)', 0, True, '0');
  Test({LINENUM}1955, 'SetMinLength(SetNumberBase(0, 16), 1)', 0, True, '0');
  Test({LINENUM}1956, 'SetMinLength(SetNumberBase(0, 16), 2)', 0, True, '00');
  Test({LINENUM}1957, 'SetMinLength(SetNumberBase(0, 16), 8)', 0, True, '00000000');
  Test({LINENUM}1958, 'SetMinLength(SetNumberBase(0, 16), 100)', 0, True, '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000');

  Test({LINENUM}1960, 'SetMinLength(SetNumberBase(123456789123456789, 16), 0)', 123456789123456789, True, '1B69B4BACD05F15');
  Test({LINENUM}1961, 'SetMinLength(SetNumberBase(123456789123456789, 16), 1)', 123456789123456789, True, '1B69B4BACD05F15');
  Test({LINENUM}1962, 'SetMinLength(SetNumberBase(123456789123456789, 16), 8)', 123456789123456789, True, '1B69B4BACD05F15');
  Test({LINENUM}1963, 'SetMinLength(SetNumberBase(123456789123456789, 16), 15)', 123456789123456789, True, '1B69B4BACD05F15');
  Test({LINENUM}1964, 'SetMinLength(SetNumberBase(123456789123456789, 16), 16)', 123456789123456789, True, '01B69B4BACD05F15');
  Test({LINENUM}1965, 'SetMinLength(SetNumberBase(123456789123456789, 16), 32)', 123456789123456789, True, '000000000000000001B69B4BACD05F15');

  Test({LINENUM}1967, 'SetMinLength(SetNumberBase(-123456789123456789, 16), 0)', -123456789123456789, True, MINUS_SIGN + '1B69B4BACD05F15');
  Test({LINENUM}1968, 'SetMinLength(SetNumberBase(-123456789123456789, 16), 1)', -123456789123456789, True, MINUS_SIGN + '1B69B4BACD05F15');
  Test({LINENUM}1969, 'SetMinLength(SetNumberBase(-123456789123456789, 16), 8)', -123456789123456789, True, MINUS_SIGN + '1B69B4BACD05F15');
  Test({LINENUM}1970, 'SetMinLength(SetNumberBase(-123456789123456789, 16), 15)', -123456789123456789, True, MINUS_SIGN + '1B69B4BACD05F15');
  Test({LINENUM}1971, 'SetMinLength(SetNumberBase(-123456789123456789, 16), 16)', -123456789123456789, True, MINUS_SIGN + '01B69B4BACD05F15');
  Test({LINENUM}1972, 'SetMinLength(SetNumberBase(-123456789123456789, 16), 32)', -123456789123456789, True, MINUS_SIGN + '000000000000000001B69B4BACD05F15');

  Test({LINENUM}1974, 'SetMinLength(SetNumberBase(255, 2), 0)', 255, True, '11111111');
  Test({LINENUM}1975, 'SetMinLength(SetNumberBase(255, 2), 1)', 255, True, '11111111');
  Test({LINENUM}1976, 'SetMinLength(SetNumberBase(255, 2), 2)', 255, True, '11111111');
  Test({LINENUM}1977, 'SetMinLength(SetNumberBase(255, 2), 3)', 255, True, '11111111');
  Test({LINENUM}1978, 'SetMinLength(SetNumberBase(255, 2), 4)', 255, True, '11111111');
  Test({LINENUM}1979, 'SetMinLength(SetNumberBase(255, 2), 5)', 255, True, '11111111');
  Test({LINENUM}1980, 'SetMinLength(SetNumberBase(255, 2), 6)', 255, True, '11111111');
  Test({LINENUM}1981, 'SetMinLength(SetNumberBase(255, 2), 7)', 255, True, '11111111');
  Test({LINENUM}1982, 'SetMinLength(SetNumberBase(255, 2), 8)', 255, True, '11111111');
  Test({LINENUM}1983, 'SetMinLength(SetNumberBase(255, 2), 9)', 255, True, '011111111');
  Test({LINENUM}1984, 'SetMinLength(SetNumberBase(255, 2), 10)', 255, True, '0011111111');
  Test({LINENUM}1985, 'SetMinLength(SetNumberBase(255, 2), 11)', 255, True, '00011111111');
  Test({LINENUM}1986, 'SetMinLength(SetNumberBase(255, 2), 12)', 255, True, '000011111111');
  Test({LINENUM}1987, 'SetMinLength(SetNumberBase(255, 2), 13)', 255, True, '0000011111111');
  Test({LINENUM}1988, 'SetMinLength(SetNumberBase(255, 2), 14)', 255, True, '00000011111111');
  Test({LINENUM}1989, 'SetMinLength(SetNumberBase(255, 2), 15)', 255, True, '000000011111111');
  Test({LINENUM}1990, 'SetMinLength(SetNumberBase(255, 2), 16)', 255, True, '0000000011111111');
  Test({LINENUM}1991, 'SetMinLength(SetNumberBase(255, 2), 32)', 255, True, '00000000000000000000000011111111');

  Test({LINENUM}1993, 'SetMinLength(SetNumberBase(-255, 2), 0)', -255, True, MINUS_SIGN + '11111111');
  Test({LINENUM}1994, 'SetMinLength(SetNumberBase(-255, 2), 1)', -255, True, MINUS_SIGN + '11111111');
  Test({LINENUM}1995, 'SetMinLength(SetNumberBase(-255, 2), 2)', -255, True, MINUS_SIGN + '11111111');
  Test({LINENUM}1996, 'SetMinLength(SetNumberBase(-255, 2), 3)', -255, True, MINUS_SIGN + '11111111');
  Test({LINENUM}1997, 'SetMinLength(SetNumberBase(-255, 2), 4)', -255, True, MINUS_SIGN + '11111111');
  Test({LINENUM}1998, 'SetMinLength(SetNumberBase(-255, 2), 5)', -255, True, MINUS_SIGN + '11111111');
  Test({LINENUM}1999, 'SetMinLength(SetNumberBase(-255, 2), 6)', -255, True, MINUS_SIGN + '11111111');
  Test({LINENUM}2000, 'SetMinLength(SetNumberBase(-255, 2), 7)', -255, True, MINUS_SIGN + '11111111');
  Test({LINENUM}2001, 'SetMinLength(SetNumberBase(-255, 2), 8)', -255, True, MINUS_SIGN + '11111111');
  Test({LINENUM}2002, 'SetMinLength(SetNumberBase(-255, 2), 9)', -255, True, MINUS_SIGN + '011111111');
  Test({LINENUM}2003, 'SetMinLength(SetNumberBase(-255, 2), 10)', -255, True, MINUS_SIGN + '0011111111');
  Test({LINENUM}2004, 'SetMinLength(SetNumberBase(-255, 2), 11)', -255, True, MINUS_SIGN + '00011111111');
  Test({LINENUM}2005, 'SetMinLength(SetNumberBase(-255, 2), 12)', -255, True, MINUS_SIGN + '000011111111');
  Test({LINENUM}2006, 'SetMinLength(SetNumberBase(-255, 2), 13)', -255, True, MINUS_SIGN + '0000011111111');
  Test({LINENUM}2007, 'SetMinLength(SetNumberBase(-255, 2), 14)', -255, True, MINUS_SIGN + '00000011111111');
  Test({LINENUM}2008, 'SetMinLength(SetNumberBase(-255, 2), 15)', -255, True, MINUS_SIGN + '000000011111111');
  Test({LINENUM}2009, 'SetMinLength(SetNumberBase(-255, 2), 16)', -255, True, MINUS_SIGN + '0000000011111111');
  Test({LINENUM}2010, 'SetMinLength(SetNumberBase(-255, 2), 32)', -255, True, MINUS_SIGN + '00000000000000000000000011111111');

  Test({LINENUM}2012, 'SetMinLength(SetNumberBase(0, 2), 0)', 0, True, '0');
  Test({LINENUM}2013, 'SetMinLength(SetNumberBase(0, 2), 1)', 0, True, '0');
  Test({LINENUM}2014, 'SetMinLength(SetNumberBase(0, 2), 2)', 0, True, '00');
  Test({LINENUM}2015, 'SetMinLength(SetNumberBase(0, 2), 8)', 0, True, '00000000');
  Test({LINENUM}2016, 'SetMinLength(SetNumberBase(0, 2), 100)', 0, True, '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000');

  Test({LINENUM}2018, 'SetMinLength(SetNumberBase(123456789123456789, 2), 0)', 123456789123456789, True, '110110110100110110100101110101100110100000101111100010101');
  Test({LINENUM}2019, 'SetMinLength(SetNumberBase(123456789123456789, 2), 1)', 123456789123456789, True, '110110110100110110100101110101100110100000101111100010101');
  Test({LINENUM}2020, 'SetMinLength(SetNumberBase(123456789123456789, 2), 32)', 123456789123456789, True, '110110110100110110100101110101100110100000101111100010101');
  Test({LINENUM}2021, 'SetMinLength(SetNumberBase(123456789123456789, 2), 57)', 123456789123456789, True, '110110110100110110100101110101100110100000101111100010101');
  Test({LINENUM}2022, 'SetMinLength(SetNumberBase(123456789123456789, 2), 64)', 123456789123456789, True, '0000000110110110100110110100101110101100110100000101111100010101');

  Test({LINENUM}2024, 'SetMinLength(SetNumberBase(-123456789123456789, 2), 0)', -123456789123456789, True, MINUS_SIGN + '110110110100110110100101110101100110100000101111100010101');
  Test({LINENUM}2025, 'SetMinLength(SetNumberBase(-123456789123456789, 2), 1)', -123456789123456789, True, MINUS_SIGN + '110110110100110110100101110101100110100000101111100010101');
  Test({LINENUM}2026, 'SetMinLength(SetNumberBase(-123456789123456789, 2), 32)', -123456789123456789, True, MINUS_SIGN + '110110110100110110100101110101100110100000101111100010101');
  Test({LINENUM}2027, 'SetMinLength(SetNumberBase(-123456789123456789, 2), 57)', -123456789123456789, True, MINUS_SIGN + '110110110100110110100101110101100110100000101111100010101');
  Test({LINENUM}2028, 'SetMinLength(SetNumberBase(-123456789123456789, 2), 64)', -123456789123456789, True, MINUS_SIGN + '0000000110110110100110110100101110101100110100000101111100010101');

  Test({LINENUM}2030, 'SetMinLength(SetNumberBase(9223372036854775807, 36), 16)', 9223372036854775807, True, '0001Y2P0IJ32E8E7');

  Test({LINENUM}2032, 'SetNumberBase(SetMinLength(-255, 8), 16)', -255, True, MINUS_SIGN + '000000FF');
  Test({LINENUM}2033, 'SetNumberBase(SetMinLength(123456789123456789, 64), 2)', 123456789123456789, True, '0000000110110110100110110100101110101100110100000101111100010101');

  // Format: digit grouping

  Test({LINENUM}2037, 'SetDigitGrouping(123456789, 3)', 123456789, True, fs('123 456 789'));

  Test({LINENUM}2039, 'SetDigitGrouping(123456789, 0)', 123456789, True, fs('123456789'));
  Test({LINENUM}2040, 'SetDigitGrouping(123456789, 1)', 123456789, True, fs('1 2 3 4 5 6 7 8 9'));
  Test({LINENUM}2041, 'SetDigitGrouping(123456789, 2)', 123456789, True, fs('1 23 45 67 89'));
  Test({LINENUM}2042, 'SetDigitGrouping(123456789, 3)', 123456789, True, fs('123 456 789'));
  Test({LINENUM}2043, 'SetDigitGrouping(123456789, 4)', 123456789, True, fs('1 2345 6789'));
  Test({LINENUM}2044, 'SetDigitGrouping(123456789, 5)', 123456789, True, fs('1234 56789'));
  Test({LINENUM}2045, 'SetDigitGrouping(123456789, 6)', 123456789, True, fs('123 456789'));
  Test({LINENUM}2046, 'SetDigitGrouping(123456789, 7)', 123456789, True, fs('12 3456789'));
  Test({LINENUM}2047, 'SetDigitGrouping(123456789, 8)', 123456789, True, fs('1 23456789'));
  Test({LINENUM}2048, 'SetDigitGrouping(123456789, 9)', 123456789, True, fs('123456789'));
  Test({LINENUM}2049, 'SetDigitGrouping(123456789, 10)', 123456789, True, fs('123456789'));
  Test({LINENUM}2050, 'SetDigitGrouping(123456789, 11)', 123456789, True, fs('123456789'));
  Test({LINENUM}2051, 'SetDigitGrouping(123456789, 12)', 123456789, True, fs('123456789'));
  Test({LINENUM}2052, 'SetDigitGrouping(123456789, 13)', 123456789, True, fs('123456789'));
  Test({LINENUM}2053, 'SetDigitGrouping(123456789, 14)', 123456789, True, fs('123456789'));
  Test({LINENUM}2054, 'SetDigitGrouping(123456789, 15)', 123456789, True, fs('123456789'));
  Test({LINENUM}2055, 'SetDigitGrouping(123456789, 16)', 123456789, True, fs('123456789'));

  Test({LINENUM}2057, 'SetDigitGrouping(-123456789, 0)', -123456789, True, MINUS_SIGN + fs('123456789'));
  Test({LINENUM}2058, 'SetDigitGrouping(-123456789, 1)', -123456789, True, MINUS_SIGN + fs('1 2 3 4 5 6 7 8 9'));
  Test({LINENUM}2059, 'SetDigitGrouping(-123456789, 2)', -123456789, True, MINUS_SIGN + fs('1 23 45 67 89'));
  Test({LINENUM}2060, 'SetDigitGrouping(-123456789, 3)', -123456789, True, MINUS_SIGN + fs('123 456 789'));
  Test({LINENUM}2061, 'SetDigitGrouping(-123456789, 4)', -123456789, True, MINUS_SIGN + fs('1 2345 6789'));
  Test({LINENUM}2062, 'SetDigitGrouping(-123456789, 5)', -123456789, True, MINUS_SIGN + fs('1234 56789'));
  Test({LINENUM}2063, 'SetDigitGrouping(-123456789, 6)', -123456789, True, MINUS_SIGN + fs('123 456789'));
  Test({LINENUM}2064, 'SetDigitGrouping(-123456789, 7)', -123456789, True, MINUS_SIGN + fs('12 3456789'));
  Test({LINENUM}2065, 'SetDigitGrouping(-123456789, 8)', -123456789, True, MINUS_SIGN + fs('1 23456789'));
  Test({LINENUM}2066, 'SetDigitGrouping(-123456789, 9)', -123456789, True, MINUS_SIGN + fs('123456789'));
  Test({LINENUM}2067, 'SetDigitGrouping(-123456789, 10)', -123456789, True, MINUS_SIGN + fs('123456789'));
  Test({LINENUM}2068, 'SetDigitGrouping(-123456789, 11)', -123456789, True, MINUS_SIGN + fs('123456789'));
  Test({LINENUM}2069, 'SetDigitGrouping(-123456789, 12)', -123456789, True, MINUS_SIGN + fs('123456789'));
  Test({LINENUM}2070, 'SetDigitGrouping(-123456789, 13)', -123456789, True, MINUS_SIGN + fs('123456789'));
  Test({LINENUM}2071, 'SetDigitGrouping(-123456789, 14)', -123456789, True, MINUS_SIGN + fs('123456789'));
  Test({LINENUM}2072, 'SetDigitGrouping(-123456789, 15)', -123456789, True, MINUS_SIGN + fs('123456789'));
  Test({LINENUM}2073, 'SetDigitGrouping(-123456789, 16)', -123456789, True, MINUS_SIGN + fs('123456789'));

  Test({LINENUM}2075, 'SetDigitGrouping(0, 0)', 0, True, fs('0'));
  Test({LINENUM}2076, 'SetDigitGrouping(0, 1)', 0, True, fs('0'));
  Test({LINENUM}2077, 'SetDigitGrouping(0, 2)', 0, True, fs('0'));
  Test({LINENUM}2078, 'SetDigitGrouping(0, 3)', 0, True, fs('0'));
  Test({LINENUM}2079, 'SetDigitGrouping(0, 4)', 0, True, fs('0'));
  Test({LINENUM}2080, 'SetDigitGrouping(0, 5)', 0, True, fs('0'));
  Test({LINENUM}2081, 'SetDigitGrouping(0, 6)', 0, True, fs('0'));
  Test({LINENUM}2082, 'SetDigitGrouping(0, 7)', 0, True, fs('0'));
  Test({LINENUM}2083, 'SetDigitGrouping(0, 8)', 0, True, fs('0'));
  Test({LINENUM}2084, 'SetDigitGrouping(0, 9)', 0, True, fs('0'));
  Test({LINENUM}2085, 'SetDigitGrouping(0, 10)', 0, True, fs('0'));
  Test({LINENUM}2086, 'SetDigitGrouping(0, 11)', 0, True, fs('0'));
  Test({LINENUM}2087, 'SetDigitGrouping(0, 12)', 0, True, fs('0'));
  Test({LINENUM}2088, 'SetDigitGrouping(0, 13)', 0, True, fs('0'));
  Test({LINENUM}2089, 'SetDigitGrouping(0, 14)', 0, True, fs('0'));
  Test({LINENUM}2090, 'SetDigitGrouping(0, 15)', 0, True, fs('0'));
  Test({LINENUM}2091, 'SetDigitGrouping(0, 16)', 0, True, fs('0'));

  Test({LINENUM}2093, 'SetDigitGrouping(123456789123456789, 0)', 123456789123456789, True, fs('123456789123456789'));
  Test({LINENUM}2094, 'SetDigitGrouping(123456789123456789, 1)', 123456789123456789, True, fs('1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9'));
  Test({LINENUM}2095, 'SetDigitGrouping(123456789123456789, 2)', 123456789123456789, True, fs('12 34 56 78 91 23 45 67 89'));
  Test({LINENUM}2096, 'SetDigitGrouping(123456789123456789, 3)', 123456789123456789, True, fs('123 456 789 123 456 789'));
  Test({LINENUM}2097, 'SetDigitGrouping(123456789123456789, 4)', 123456789123456789, True, fs('12 3456 7891 2345 6789'));
  Test({LINENUM}2098, 'SetDigitGrouping(123456789123456789, 5)', 123456789123456789, True, fs('123 45678 91234 56789'));
  Test({LINENUM}2099, 'SetDigitGrouping(123456789123456789, 6)', 123456789123456789, True, fs('123456 789123 456789'));
  Test({LINENUM}2100, 'SetDigitGrouping(123456789123456789, 7)', 123456789123456789, True, fs('1234 5678912 3456789'));
  Test({LINENUM}2101, 'SetDigitGrouping(123456789123456789, 8)', 123456789123456789, True, fs('12 34567891 23456789'));
  Test({LINENUM}2102, 'SetDigitGrouping(123456789123456789, 9)', 123456789123456789, True, fs('123456789 123456789'));
  Test({LINENUM}2103, 'SetDigitGrouping(123456789123456789, 10)', 123456789123456789, True, fs('12345678 9123456789'));
  Test({LINENUM}2104, 'SetDigitGrouping(123456789123456789, 12)', 123456789123456789, True, fs('123456 789123456789'));
  Test({LINENUM}2105, 'SetDigitGrouping(123456789123456789, 16)', 123456789123456789, True, fs('12 3456789123456789'));
  Test({LINENUM}2106, 'SetDigitGrouping(123456789123456789, 18)', 123456789123456789, True, fs('123456789123456789'));
  Test({LINENUM}2107, 'SetDigitGrouping(123456789123456789, 19)', 123456789123456789, True, fs('123456789123456789'));
  Test({LINENUM}2108, 'SetDigitGrouping(123456789123456789, 20)', 123456789123456789, True, fs('123456789123456789'));

  Test({LINENUM}2110, 'SetDigitGrouping(-123456789123456789, 0)', -123456789123456789, True, MINUS_SIGN + fs('123456789123456789'));
  Test({LINENUM}2111, 'SetDigitGrouping(-123456789123456789, 1)', -123456789123456789, True, MINUS_SIGN + fs('1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9'));
  Test({LINENUM}2112, 'SetDigitGrouping(-123456789123456789, 2)', -123456789123456789, True, MINUS_SIGN + fs('12 34 56 78 91 23 45 67 89'));
  Test({LINENUM}2113, 'SetDigitGrouping(-123456789123456789, 3)', -123456789123456789, True, MINUS_SIGN + fs('123 456 789 123 456 789'));
  Test({LINENUM}2114, 'SetDigitGrouping(-123456789123456789, 4)', -123456789123456789, True, MINUS_SIGN + fs('12 3456 7891 2345 6789'));
  Test({LINENUM}2115, 'SetDigitGrouping(-123456789123456789, 5)', -123456789123456789, True, MINUS_SIGN + fs('123 45678 91234 56789'));
  Test({LINENUM}2116, 'SetDigitGrouping(-123456789123456789, 6)', -123456789123456789, True, MINUS_SIGN + fs('123456 789123 456789'));
  Test({LINENUM}2117, 'SetDigitGrouping(-123456789123456789, 7)', -123456789123456789, True, MINUS_SIGN + fs('1234 5678912 3456789'));
  Test({LINENUM}2118, 'SetDigitGrouping(-123456789123456789, 8)', -123456789123456789, True, MINUS_SIGN + fs('12 34567891 23456789'));
  Test({LINENUM}2119, 'SetDigitGrouping(-123456789123456789, 9)', -123456789123456789, True, MINUS_SIGN + fs('123456789 123456789'));
  Test({LINENUM}2120, 'SetDigitGrouping(-123456789123456789, 10)', -123456789123456789, True, MINUS_SIGN + fs('12345678 9123456789'));
  Test({LINENUM}2121, 'SetDigitGrouping(-123456789123456789, 12)', -123456789123456789, True, MINUS_SIGN + fs('123456 789123456789'));
  Test({LINENUM}2122, 'SetDigitGrouping(-123456789123456789, 16)', -123456789123456789, True, MINUS_SIGN + fs('12 3456789123456789'));
  Test({LINENUM}2123, 'SetDigitGrouping(-123456789123456789, 18)', -123456789123456789, True, MINUS_SIGN + fs('123456789123456789'));
  Test({LINENUM}2124, 'SetDigitGrouping(-123456789123456789, 19)', -123456789123456789, True, MINUS_SIGN + fs('123456789123456789'));
  Test({LINENUM}2125, 'SetDigitGrouping(-123456789123456789, 20)', -123456789123456789, True, MINUS_SIGN + fs('123456789123456789'));

  Test({LINENUM}2127, 'SetDigitGrouping(7, 0)', 7, True, fs('7'));
  Test({LINENUM}2128, 'SetDigitGrouping(7, 1)', 7, True, fs('7'));
  Test({LINENUM}2129, 'SetDigitGrouping(7, 2)', 7, True, fs('7'));
  Test({LINENUM}2130, 'SetDigitGrouping(7, 3)', 7, True, fs('7'));
  Test({LINENUM}2131, 'SetDigitGrouping(7, 4)', 7, True, fs('7'));
  Test({LINENUM}2132, 'SetDigitGrouping(7, 5)', 7, True, fs('7'));
  Test({LINENUM}2133, 'SetDigitGrouping(7, 6)', 7, True, fs('7'));
  Test({LINENUM}2134, 'SetDigitGrouping(7, 7)', 7, True, fs('7'));
  Test({LINENUM}2135, 'SetDigitGrouping(7, 8)', 7, True, fs('7'));
  Test({LINENUM}2136, 'SetDigitGrouping(7, 9)', 7, True, fs('7'));
  Test({LINENUM}2137, 'SetDigitGrouping(7, 10)', 7, True, fs('7'));
  Test({LINENUM}2138, 'SetDigitGrouping(7, 11)', 7, True, fs('7'));
  Test({LINENUM}2139, 'SetDigitGrouping(7, 12)', 7, True, fs('7'));
  Test({LINENUM}2140, 'SetDigitGrouping(7, 13)', 7, True, fs('7'));
  Test({LINENUM}2141, 'SetDigitGrouping(7, 14)', 7, True, fs('7'));
  Test({LINENUM}2142, 'SetDigitGrouping(7, 15)', 7, True, fs('7'));
  Test({LINENUM}2143, 'SetDigitGrouping(7, 16)', 7, True, fs('7'));

  Test({LINENUM}2145, 'SetDigitGrouping(-7, 0)', -7, True, MINUS_SIGN + fs('7'));
  Test({LINENUM}2146, 'SetDigitGrouping(-7, 1)', -7, True, MINUS_SIGN + fs('7'));
  Test({LINENUM}2147, 'SetDigitGrouping(-7, 2)', -7, True, MINUS_SIGN + fs('7'));
  Test({LINENUM}2148, 'SetDigitGrouping(-7, 3)', -7, True, MINUS_SIGN + fs('7'));
  Test({LINENUM}2149, 'SetDigitGrouping(-7, 4)', -7, True, MINUS_SIGN + fs('7'));
  Test({LINENUM}2150, 'SetDigitGrouping(-7, 5)', -7, True, MINUS_SIGN + fs('7'));
  Test({LINENUM}2151, 'SetDigitGrouping(-7, 6)', -7, True, MINUS_SIGN + fs('7'));
  Test({LINENUM}2152, 'SetDigitGrouping(-7, 7)', -7, True, MINUS_SIGN + fs('7'));
  Test({LINENUM}2153, 'SetDigitGrouping(-7, 8)', -7, True, MINUS_SIGN + fs('7'));
  Test({LINENUM}2154, 'SetDigitGrouping(-7, 9)', -7, True, MINUS_SIGN + fs('7'));
  Test({LINENUM}2155, 'SetDigitGrouping(-7, 10)', -7, True, MINUS_SIGN + fs('7'));
  Test({LINENUM}2156, 'SetDigitGrouping(-7, 11)', -7, True, MINUS_SIGN + fs('7'));
  Test({LINENUM}2157, 'SetDigitGrouping(-7, 12)', -7, True, MINUS_SIGN + fs('7'));
  Test({LINENUM}2158, 'SetDigitGrouping(-7, 13)', -7, True, MINUS_SIGN + fs('7'));
  Test({LINENUM}2159, 'SetDigitGrouping(-7, 14)', -7, True, MINUS_SIGN + fs('7'));
  Test({LINENUM}2160, 'SetDigitGrouping(-7, 15)', -7, True, MINUS_SIGN + fs('7'));
  Test({LINENUM}2161, 'SetDigitGrouping(-7, 16)', -7, True, MINUS_SIGN + fs('7'));

  Test({LINENUM}2163, 'SetDigitGrouping(123456, 127)', 123456, True, fs('123456'));
  Test({LINENUM}2164, 'SetDigitGrouping(123456, 128)', failure, 'Invalid digit grouping size 128.');
  Test({LINENUM}2165, 'SetDigitGrouping(123456, -1)', 123456, True, fs('123456'));
  Test({LINENUM}2166, 'SetDigitGrouping(123456, 2.2)', failure, 'An object of type integer was expected as argument 2, but an object of type real number was given.');
  Test({LINENUM}2167, 'SetDigitGrouping(123456, "k")', failure, 'An object of type integer was expected as argument 2, but an object of type string was given.');
  Test({LINENUM}2168, 'SetDigitGrouping(123456, 2, 2)', failure, 'Too many arguments.');
  Test({LINENUM}2169, 'SetDigitGrouping(123456)', failure, 'Too few arguments. A required argument of type integer is missing.');

  // Format: minimum length + digit grouping

  Test({LINENUM}2173, 'SetMinLength(SetDigitGrouping(123, 0), 0)', 123, True, fs('123'));
  Test({LINENUM}2174, 'SetMinLength(SetDigitGrouping(123, 0), 6)', 123, True, fs('000123'));
  Test({LINENUM}2175, 'SetMinLength(SetDigitGrouping(123, 1), 6)', 123, True, fs('0 0 0 1 2 3'));
  Test({LINENUM}2176, 'SetMinLength(SetDigitGrouping(123, 2), 6)', 123, True, fs('00 01 23'));
  Test({LINENUM}2177, 'SetMinLength(SetDigitGrouping(123, 3), 6)', 123, True, fs('000 123'));
  Test({LINENUM}2178, 'SetMinLength(SetDigitGrouping(123, 4), 6)', 123, True, fs('00 0123'));
  Test({LINENUM}2179, 'SetMinLength(SetDigitGrouping(123, 5), 6)', 123, True, fs('0 00123'));
  Test({LINENUM}2180, 'SetMinLength(SetDigitGrouping(123, 6), 6)', 123, True, fs('000123'));
  Test({LINENUM}2181, 'SetMinLength(SetDigitGrouping(123, 7), 6)', 123, True, fs('000123'));
  Test({LINENUM}2182, 'SetMinLength(SetDigitGrouping(123, 4), 16)', 123, True, fs('0000 0000 0000 0123'));

  Test({LINENUM}2184, 'SetMinLength(SetDigitGrouping(-123, 0), 0)', -123, True, MINUS_SIGN + fs('123'));
  Test({LINENUM}2185, 'SetMinLength(SetDigitGrouping(-123, 0), 6)', -123, True, MINUS_SIGN + fs('000123'));
  Test({LINENUM}2186, 'SetMinLength(SetDigitGrouping(-123, 1), 6)', -123, True, MINUS_SIGN + fs('0 0 0 1 2 3'));
  Test({LINENUM}2187, 'SetMinLength(SetDigitGrouping(-123, 2), 6)', -123, True, MINUS_SIGN + fs('00 01 23'));
  Test({LINENUM}2188, 'SetMinLength(SetDigitGrouping(-123, 3), 6)', -123, True, MINUS_SIGN + fs('000 123'));
  Test({LINENUM}2189, 'SetMinLength(SetDigitGrouping(-123, 4), 6)', -123, True, MINUS_SIGN + fs('00 0123'));
  Test({LINENUM}2190, 'SetMinLength(SetDigitGrouping(-123, 5), 6)', -123, True, MINUS_SIGN + fs('0 00123'));
  Test({LINENUM}2191, 'SetMinLength(SetDigitGrouping(-123, 6), 6)', -123, True, MINUS_SIGN + fs('000123'));
  Test({LINENUM}2192, 'SetMinLength(SetDigitGrouping(-123, 7), 6)', -123, True, MINUS_SIGN + fs('000123'));
  Test({LINENUM}2193, 'SetMinLength(SetDigitGrouping(-123, 4), 16)', -123, True, MINUS_SIGN + fs('0000 0000 0000 0123'));

  Test({LINENUM}2195, 'SetMinLength(SetDigitGrouping(0, 0), 0)', 0, True, fs('0'));
  Test({LINENUM}2196, 'SetMinLength(SetDigitGrouping(0, 0), 8)', 0, True, fs('00000000'));
  Test({LINENUM}2197, 'SetMinLength(SetDigitGrouping(0, 2), 8)', 0, True, fs('00 00 00 00'));
  Test({LINENUM}2198, 'SetMinLength(SetDigitGrouping(0, 3), 8)', 0, True, fs('00 000 000'));
  Test({LINENUM}2199, 'SetMinLength(SetDigitGrouping(0, 4), 8)', 0, True, fs('0000 0000'));
  Test({LINENUM}2200, 'SetMinLength(SetDigitGrouping(0, 6), 8)', 0, True, fs('00 000000'));
  Test({LINENUM}2201, 'SetMinLength(SetDigitGrouping(0, 7), 8)', 0, True, fs('0 0000000'));
  Test({LINENUM}2202, 'SetMinLength(SetDigitGrouping(0, 8), 8)', 0, True, fs('00000000'));
  Test({LINENUM}2203, 'SetMinLength(SetDigitGrouping(0, 9), 8)', 0, True, fs('00000000'));

  // Format: number base + digit grouping

  Test({LINENUM}2207, 'SetDigitGrouping(SetNumberBase(123456, 10), 0)', 123456, True, fs('123456'));
  Test({LINENUM}2208, 'SetDigitGrouping(SetNumberBase(123456, 10), 2)', 123456, True, fs('12 34 56'));
  Test({LINENUM}2209, 'SetDigitGrouping(SetNumberBase(123456, 10), 3)', 123456, True, fs('123 456'));

  Test({LINENUM}2211, 'SetDigitGrouping(SetNumberBase(-123456, 10), 0)', -123456, True, MINUS_SIGN + fs('123456'));
  Test({LINENUM}2212, 'SetDigitGrouping(SetNumberBase(-123456, 10), 2)', -123456, True, MINUS_SIGN + fs('12 34 56'));
  Test({LINENUM}2213, 'SetDigitGrouping(SetNumberBase(-123456, 10), 3)', -123456, True, MINUS_SIGN + fs('123 456'));

  Test({LINENUM}2215, 'SetDigitGrouping(SetNumberBase(0, 10), 0)', 0, True, fs('0'));
  Test({LINENUM}2216, 'SetDigitGrouping(SetNumberBase(0, 10), 2)', 0, True, fs('0'));
  Test({LINENUM}2217, 'SetDigitGrouping(SetNumberBase(0, 10), 3)', 0, True, fs('0'));

  Test({LINENUM}2219, 'SetDigitGrouping(SetNumberBase(123456789123456789, 16), 0)', 123456789123456789, True, fs('1B69B4BACD05F15'));
  Test({LINENUM}2220, 'SetDigitGrouping(SetNumberBase(123456789123456789, 16), 1)', 123456789123456789, True, fs('1 B 6 9 B 4 B A C D 0 5 F 1 5'));
  Test({LINENUM}2221, 'SetDigitGrouping(SetNumberBase(123456789123456789, 16), 2)', 123456789123456789, True, fs('1 B6 9B 4B AC D0 5F 15'));
  Test({LINENUM}2222, 'SetDigitGrouping(SetNumberBase(123456789123456789, 16), 3)', 123456789123456789, True, fs('1B6 9B4 BAC D05 F15'));
  Test({LINENUM}2223, 'SetDigitGrouping(SetNumberBase(123456789123456789, 16), 4)', 123456789123456789, True, fs('1B6 9B4B ACD0 5F15'));
  Test({LINENUM}2224, 'SetDigitGrouping(SetNumberBase(123456789123456789, 16), 5)', 123456789123456789, True, fs('1B69B 4BACD 05F15'));
  Test({LINENUM}2225, 'SetDigitGrouping(SetNumberBase(123456789123456789, 16), 6)', 123456789123456789, True, fs('1B6 9B4BAC D05F15'));
  Test({LINENUM}2226, 'SetDigitGrouping(SetNumberBase(123456789123456789, 16), 7)', 123456789123456789, True, fs('1 B69B4BA CD05F15'));
  Test({LINENUM}2227, 'SetDigitGrouping(SetNumberBase(123456789123456789, 16), 8)', 123456789123456789, True, fs('1B69B4B ACD05F15'));
  Test({LINENUM}2228, 'SetDigitGrouping(SetNumberBase(123456789123456789, 16), 9)', 123456789123456789, True, fs('1B69B4 BACD05F15'));
  Test({LINENUM}2229, 'SetDigitGrouping(SetNumberBase(123456789123456789, 16), 10)', 123456789123456789, True, fs('1B69B 4BACD05F15'));
  Test({LINENUM}2230, 'SetDigitGrouping(SetNumberBase(123456789123456789, 16), 12)', 123456789123456789, True, fs('1B6 9B4BACD05F15'));
  Test({LINENUM}2231, 'SetDigitGrouping(SetNumberBase(123456789123456789, 16), 14)', 123456789123456789, True, fs('1 B69B4BACD05F15'));
  Test({LINENUM}2232, 'SetDigitGrouping(SetNumberBase(123456789123456789, 16), 15)', 123456789123456789, True, fs('1B69B4BACD05F15'));
  Test({LINENUM}2233, 'SetDigitGrouping(SetNumberBase(123456789123456789, 16), 16)', 123456789123456789, True, fs('1B69B4BACD05F15'));
  Test({LINENUM}2234, 'SetDigitGrouping(SetNumberBase(123456789123456789, 16), 32)', 123456789123456789, True, fs('1B69B4BACD05F15'));

  Test({LINENUM}2236, 'SetDigitGrouping(SetNumberBase(-123456789123456789, 16), 0)', -123456789123456789, True, MINUS_SIGN + fs('1B69B4BACD05F15'));
  Test({LINENUM}2237, 'SetDigitGrouping(SetNumberBase(-123456789123456789, 16), 1)', -123456789123456789, True, MINUS_SIGN + fs('1 B 6 9 B 4 B A C D 0 5 F 1 5'));
  Test({LINENUM}2238, 'SetDigitGrouping(SetNumberBase(-123456789123456789, 16), 2)', -123456789123456789, True, MINUS_SIGN + fs('1 B6 9B 4B AC D0 5F 15'));
  Test({LINENUM}2239, 'SetDigitGrouping(SetNumberBase(-123456789123456789, 16), 3)', -123456789123456789, True, MINUS_SIGN + fs('1B6 9B4 BAC D05 F15'));
  Test({LINENUM}2240, 'SetDigitGrouping(SetNumberBase(-123456789123456789, 16), 4)', -123456789123456789, True, MINUS_SIGN + fs('1B6 9B4B ACD0 5F15'));
  Test({LINENUM}2241, 'SetDigitGrouping(SetNumberBase(-123456789123456789, 16), 5)', -123456789123456789, True, MINUS_SIGN + fs('1B69B 4BACD 05F15'));
  Test({LINENUM}2242, 'SetDigitGrouping(SetNumberBase(-123456789123456789, 16), 6)', -123456789123456789, True, MINUS_SIGN + fs('1B6 9B4BAC D05F15'));
  Test({LINENUM}2243, 'SetDigitGrouping(SetNumberBase(-123456789123456789, 16), 7)', -123456789123456789, True, MINUS_SIGN + fs('1 B69B4BA CD05F15'));
  Test({LINENUM}2244, 'SetDigitGrouping(SetNumberBase(-123456789123456789, 16), 8)', -123456789123456789, True, MINUS_SIGN + fs('1B69B4B ACD05F15'));
  Test({LINENUM}2245, 'SetDigitGrouping(SetNumberBase(-123456789123456789, 16), 9)', -123456789123456789, True, MINUS_SIGN + fs('1B69B4 BACD05F15'));
  Test({LINENUM}2246, 'SetDigitGrouping(SetNumberBase(-123456789123456789, 16), 10)', -123456789123456789, True, MINUS_SIGN + fs('1B69B 4BACD05F15'));
  Test({LINENUM}2247, 'SetDigitGrouping(SetNumberBase(-123456789123456789, 16), 12)', -123456789123456789, True, MINUS_SIGN + fs('1B6 9B4BACD05F15'));
  Test({LINENUM}2248, 'SetDigitGrouping(SetNumberBase(-123456789123456789, 16), 14)', -123456789123456789, True, MINUS_SIGN + fs('1 B69B4BACD05F15'));
  Test({LINENUM}2249, 'SetDigitGrouping(SetNumberBase(-123456789123456789, 16), 15)', -123456789123456789, True, MINUS_SIGN + fs('1B69B4BACD05F15'));
  Test({LINENUM}2250, 'SetDigitGrouping(SetNumberBase(-123456789123456789, 16), 16)', -123456789123456789, True, MINUS_SIGN + fs('1B69B4BACD05F15'));
  Test({LINENUM}2251, 'SetDigitGrouping(SetNumberBase(-123456789123456789, 16), 32)', -123456789123456789, True, MINUS_SIGN + fs('1B69B4BACD05F15'));

  Test({LINENUM}2253, 'SetDigitGrouping(SetNumberBase(0, 16), 0)', 0, True, fs('0'));
  Test({LINENUM}2254, 'SetDigitGrouping(SetNumberBase(0, 16), 1)', 0, True, fs('0'));
  Test({LINENUM}2255, 'SetDigitGrouping(SetNumberBase(0, 16), 2)', 0, True, fs('0'));
  Test({LINENUM}2256, 'SetDigitGrouping(SetNumberBase(0, 16), 3)', 0, True, fs('0'));

  Test({LINENUM}2258, 'SetDigitGrouping(SetNumberBase(123, 2), 0)', 123, True, fs('1111011'));
  Test({LINENUM}2259, 'SetDigitGrouping(SetNumberBase(123, 2), 1)', 123, True, fs('1 1 1 1 0 1 1'));
  Test({LINENUM}2260, 'SetDigitGrouping(SetNumberBase(123, 2), 2)', 123, True, fs('1 11 10 11'));
  Test({LINENUM}2261, 'SetDigitGrouping(SetNumberBase(123, 2), 3)', 123, True, fs('1 111 011'));
  Test({LINENUM}2262, 'SetDigitGrouping(SetNumberBase(123, 2), 4)', 123, True, fs('111 1011'));
  Test({LINENUM}2263, 'SetDigitGrouping(SetNumberBase(123, 2), 5)', 123, True, fs('11 11011'));
  Test({LINENUM}2264, 'SetDigitGrouping(SetNumberBase(123, 2), 6)', 123, True, fs('1 111011'));
  Test({LINENUM}2265, 'SetDigitGrouping(SetNumberBase(123, 2), 7)', 123, True, fs('1111011'));
  Test({LINENUM}2266, 'SetDigitGrouping(SetNumberBase(123, 2), 8)', 123, True, fs('1111011'));
  Test({LINENUM}2267, 'SetDigitGrouping(SetNumberBase(123, 2), 64)', 123, True, fs('1111011'));

  Test({LINENUM}2269, 'SetDigitGrouping(SetNumberBase(-123, 2), 0)', -123, True, MINUS_SIGN + fs('1111011'));
  Test({LINENUM}2270, 'SetDigitGrouping(SetNumberBase(-123, 2), 1)', -123, True, MINUS_SIGN + fs('1 1 1 1 0 1 1'));
  Test({LINENUM}2271, 'SetDigitGrouping(SetNumberBase(-123, 2), 2)', -123, True, MINUS_SIGN + fs('1 11 10 11'));
  Test({LINENUM}2272, 'SetDigitGrouping(SetNumberBase(-123, 2), 3)', -123, True, MINUS_SIGN + fs('1 111 011'));
  Test({LINENUM}2273, 'SetDigitGrouping(SetNumberBase(-123, 2), 4)', -123, True, MINUS_SIGN + fs('111 1011'));
  Test({LINENUM}2274, 'SetDigitGrouping(SetNumberBase(-123, 2), 5)', -123, True, MINUS_SIGN + fs('11 11011'));
  Test({LINENUM}2275, 'SetDigitGrouping(SetNumberBase(-123, 2), 6)', -123, True, MINUS_SIGN + fs('1 111011'));
  Test({LINENUM}2276, 'SetDigitGrouping(SetNumberBase(-123, 2), 7)', -123, True, MINUS_SIGN + fs('1111011'));
  Test({LINENUM}2277, 'SetDigitGrouping(SetNumberBase(-123, 2), 8)', -123, True, MINUS_SIGN + fs('1111011'));
  Test({LINENUM}2278, 'SetDigitGrouping(SetNumberBase(-123, 2), 64)', -123, True, MINUS_SIGN + fs('1111011'));

  Test({LINENUM}2280, 'SetDigitGrouping(SetNumberBase(123456789123456789, 2), 0)', 123456789123456789, True, fs('110110110100110110100101110101100110100000101111100010101'));
  Test({LINENUM}2281, 'SetDigitGrouping(SetNumberBase(123456789123456789, 2), 1)', 123456789123456789, True, fs('1 1 0 1 1 0 1 1 0 1 0 0 1 1 0 1 1 0 1 0 0 1 0 1 1 1 0 1 0 1 1 0 0 1 1 0 1 0 0 0 0 0 1 0 1 1 1 1 1 0 0 0 1 0 1 0 1'));
  Test({LINENUM}2282, 'SetDigitGrouping(SetNumberBase(123456789123456789, 2), 2)', 123456789123456789, True, fs('1 10 11 01 10 10 01 10 11 01 00 10 11 10 10 11 00 11 01 00 00 01 01 11 11 00 01 01 01'));
  Test({LINENUM}2283, 'SetDigitGrouping(SetNumberBase(123456789123456789, 2), 8)', 123456789123456789, True, fs('1 10110110 10011011 01001011 10101100 11010000 01011111 00010101'));
  Test({LINENUM}2284, 'SetDigitGrouping(SetNumberBase(123456789123456789, 2), 32)', 123456789123456789, True, fs('1101101101001101101001011 10101100110100000101111100010101'));

  Test({LINENUM}2286, 'SetDigitGrouping(SetNumberBase(-123456789123456789, 2), 0)', -123456789123456789, True, MINUS_SIGN + fs('110110110100110110100101110101100110100000101111100010101'));
  Test({LINENUM}2287, 'SetDigitGrouping(SetNumberBase(-123456789123456789, 2), 1)', -123456789123456789, True, MINUS_SIGN + fs('1 1 0 1 1 0 1 1 0 1 0 0 1 1 0 1 1 0 1 0 0 1 0 1 1 1 0 1 0 1 1 0 0 1 1 0 1 0 0 0 0 0 1 0 1 1 1 1 1 0 0 0 1 0 1 0 1'));
  Test({LINENUM}2288, 'SetDigitGrouping(SetNumberBase(-123456789123456789, 2), 2)', -123456789123456789, True, MINUS_SIGN + fs('1 10 11 01 10 10 01 10 11 01 00 10 11 10 10 11 00 11 01 00 00 01 01 11 11 00 01 01 01'));
  Test({LINENUM}2289, 'SetDigitGrouping(SetNumberBase(-123456789123456789, 2), 8)', -123456789123456789, True, MINUS_SIGN + fs('1 10110110 10011011 01001011 10101100 11010000 01011111 00010101'));
  Test({LINENUM}2290, 'SetDigitGrouping(SetNumberBase(-123456789123456789, 2), 32)', -123456789123456789, True, MINUS_SIGN + fs('1101101101001101101001011 10101100110100000101111100010101'));

  Test({LINENUM}2292, 'SetDigitGrouping(SetNumberBase(0, 2), 0)', 0, True, fs('0'));
  Test({LINENUM}2293, 'SetDigitGrouping(SetNumberBase(0, 2), 1)', 0, True, fs('0'));
  Test({LINENUM}2294, 'SetDigitGrouping(SetNumberBase(0, 2), 2)', 0, True, fs('0'));
  Test({LINENUM}2295, 'SetDigitGrouping(SetNumberBase(0, 2), 3)', 0, True, fs('0'));

  Test({LINENUM}2297, 'SetDigitGrouping(SetNumberBase(9223372036854775807, 36), 0)', 9223372036854775807, True, fs('1Y2P0IJ32E8E7'));
  Test({LINENUM}2298, 'SetDigitGrouping(SetNumberBase(9223372036854775807, 36), 1)', 9223372036854775807, True, fs('1 Y 2 P 0 I J 3 2 E 8 E 7'));
  Test({LINENUM}2299, 'SetDigitGrouping(SetNumberBase(9223372036854775807, 36), 2)', 9223372036854775807, True, fs('1 Y2 P0 IJ 32 E8 E7'));
  Test({LINENUM}2300, 'SetDigitGrouping(SetNumberBase(9223372036854775807, 36), 3)', 9223372036854775807, True, fs('1 Y2P 0IJ 32E 8E7'));
  Test({LINENUM}2301, 'SetDigitGrouping(SetNumberBase(9223372036854775807, 36), 4)', 9223372036854775807, True, fs('1 Y2P0 IJ32 E8E7'));
  Test({LINENUM}2302, 'SetDigitGrouping(SetNumberBase(9223372036854775807, 36), 8)', 9223372036854775807, True, fs('1Y2P0 IJ32E8E7'));
  Test({LINENUM}2303, 'SetDigitGrouping(SetNumberBase(9223372036854775807, 36), 16)', 9223372036854775807, True, fs('1Y2P0IJ32E8E7'));

  Test({LINENUM}2305, 'SetDigitGrouping(SetNumberBase(-9223372036854775807, 36), 0)', -9223372036854775807, True, MINUS_SIGN + fs('1Y2P0IJ32E8E7'));
  Test({LINENUM}2306, 'SetDigitGrouping(SetNumberBase(-9223372036854775807, 36), 1)', -9223372036854775807, True, MINUS_SIGN + fs('1 Y 2 P 0 I J 3 2 E 8 E 7'));
  Test({LINENUM}2307, 'SetDigitGrouping(SetNumberBase(-9223372036854775807, 36), 2)', -9223372036854775807, True, MINUS_SIGN + fs('1 Y2 P0 IJ 32 E8 E7'));
  Test({LINENUM}2308, 'SetDigitGrouping(SetNumberBase(-9223372036854775807, 36), 3)', -9223372036854775807, True, MINUS_SIGN + fs('1 Y2P 0IJ 32E 8E7'));
  Test({LINENUM}2309, 'SetDigitGrouping(SetNumberBase(-9223372036854775807, 36), 4)', -9223372036854775807, True, MINUS_SIGN + fs('1 Y2P0 IJ32 E8E7'));
  Test({LINENUM}2310, 'SetDigitGrouping(SetNumberBase(-9223372036854775807, 36), 8)', -9223372036854775807, True, MINUS_SIGN + fs('1Y2P0 IJ32E8E7'));
  Test({LINENUM}2311, 'SetDigitGrouping(SetNumberBase(-9223372036854775807, 36), 16)', -9223372036854775807, True, MINUS_SIGN + fs('1Y2P0IJ32E8E7'));

  Test({LINENUM}2313, 'SetDigitGrouping(SetNumberBase(0, 36), 4)', 0, True, fs('0'));

  // Format: number base + digit grouping + minimum length

  Test({LINENUM}2317, 'SetMinLength(SetDigitGrouping(SetNumberBase(123456, 10), 3), 10)', 123456, True, fs('0 000 123 456'));
  Test({LINENUM}2318, 'SetMinLength(SetDigitGrouping(SetNumberBase(123456, 16), 2), 8)', 123456, True, fs('00 01 E2 40'));
  Test({LINENUM}2319, 'SetMinLength(SetDigitGrouping(SetNumberBase(123456, 2), 8), 32)', 123456, True, fs('00000000 00000001 11100010 01000000'));
  Test({LINENUM}2320, 'SetMinLength(SetDigitGrouping(SetNumberBase(123456, 2), 4), 32)', 123456, True, fs('0000 0000 0000 0001 1110 0010 0100 0000'));

  Test({LINENUM}2322, 'SetMinLength(SetDigitGrouping(SetNumberBase(123456789123456789, 10), 3), 20)', 123456789123456789, True, fs('00 123 456 789 123 456 789'));
  Test({LINENUM}2323, 'SetMinLength(SetDigitGrouping(SetNumberBase(123456789123456789, 16), 2), 16)', 123456789123456789, True, fs('01 B6 9B 4B AC D0 5F 15'));
  Test({LINENUM}2324, 'SetMinLength(SetDigitGrouping(SetNumberBase(123456789123456789, 2), 8), 64)', 123456789123456789, True, fs('00000001 10110110 10011011 01001011 10101100 11010000 01011111 00010101'));

  Test({LINENUM}2326, 'SetMinLength(SetDigitGrouping(SetNumberBase(9223372036854775807, 10), 3), 20)', 9223372036854775807, True, fs('09 223 372 036 854 775 807'));
  Test({LINENUM}2327, 'SetMinLength(SetDigitGrouping(SetNumberBase(9223372036854775807, 16), 2), 16)', 9223372036854775807, True, fs('7F FF FF FF FF FF FF FF'));
  Test({LINENUM}2328, 'SetMinLength(SetDigitGrouping(SetNumberBase(9223372036854775807, 2), 8), 64)', 9223372036854775807, True, fs('01111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111'));

  Test({LINENUM}2330, 'SetMinLength(SetDigitGrouping(SetNumberBase(-123456, 10), 3), 10)', -123456, True, MINUS_SIGN + fs('0 000 123 456'));
  Test({LINENUM}2331, 'SetMinLength(SetDigitGrouping(SetNumberBase(-123456, 16), 2), 8)', -123456, True, MINUS_SIGN + fs('00 01 E2 40'));
  Test({LINENUM}2332, 'SetMinLength(SetDigitGrouping(SetNumberBase(-123456, 2), 8), 32)', -123456, True, MINUS_SIGN + fs('00000000 00000001 11100010 01000000'));
  Test({LINENUM}2333, 'SetMinLength(SetDigitGrouping(SetNumberBase(-123456, 2), 4), 32)', -123456, True, MINUS_SIGN + fs('0000 0000 0000 0001 1110 0010 0100 0000'));

  Test({LINENUM}2335, 'SetMinLength(SetDigitGrouping(SetNumberBase(-123456789123456789, 10), 3), 20)', -123456789123456789, True, MINUS_SIGN + fs('00 123 456 789 123 456 789'));
  Test({LINENUM}2336, 'SetMinLength(SetDigitGrouping(SetNumberBase(-123456789123456789, 16), 2), 16)', -123456789123456789, True, MINUS_SIGN + fs('01 B6 9B 4B AC D0 5F 15'));
  Test({LINENUM}2337, 'SetMinLength(SetDigitGrouping(SetNumberBase(-123456789123456789, 2), 8), 64)', -123456789123456789, True, MINUS_SIGN + fs('00000001 10110110 10011011 01001011 10101100 11010000 01011111 00010101'));

  Test({LINENUM}2339, 'SetMinLength(SetDigitGrouping(SetNumberBase(-9223372036854775807, 10), 3), 20)', -9223372036854775807, True, MINUS_SIGN + fs('09 223 372 036 854 775 807'));
  Test({LINENUM}2340, 'SetMinLength(SetDigitGrouping(SetNumberBase(-9223372036854775807, 16), 2), 16)', -9223372036854775807, True, MINUS_SIGN + fs('7F FF FF FF FF FF FF FF'));
  Test({LINENUM}2341, 'SetMinLength(SetDigitGrouping(SetNumberBase(-9223372036854775807, 2), 8), 64)', -9223372036854775807, True, MINUS_SIGN + fs('01111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111'));

  Test({LINENUM}2343, 'SetMinLength(SetDigitGrouping(SetNumberBase(853624750053, 2), 8), 64)', 853624750053, True, fs('00000000 00000000 00000000 11000110 10111111 11111111 11111111 11100101'));
  Test({LINENUM}2344, 'SetMinLength(SetDigitGrouping(SetNumberBase(-853624750053, 2), 8), 64)', -853624750053, True, MINUS_SIGN + fs('00000000 00000000 00000000 11000110 10111111 11111111 11111111 11100101'));

  Test({LINENUM}2346, 'SetMinLength(SetDigitGrouping(SetNumberBase(853624750053, 2), 8), 32)', 853624750053, True, fs('11000110 10111111 11111111 11111111 11100101'));
  Test({LINENUM}2347, 'SetMinLength(SetDigitGrouping(SetNumberBase(-853624750053, 2), 8), 32)', -853624750053, True, MINUS_SIGN + fs('11000110 10111111 11111111 11111111 11100101'));

  Test({LINENUM}2349, 'SetNumberBase(SetMinLength(SetDigitGrouping(853624750053, 8), 64), 2)', 853624750053, True, fs('00000000 00000000 00000000 11000110 10111111 11111111 11111111 11100101'));
  Test({LINENUM}2350, 'SetNumberBase(SetNumberBase(SetDigitGrouping(SetMinLength(853624750053, 64), 8), 36), 2)', 853624750053, True, fs('00000000 00000000 00000000 11000110 10111111 11111111 11111111 11100101'));
  Test({LINENUM}2351, 'SetMinLength(SetNumberBase(SetNumberBase(SetDigitGrouping(SetMinLength(853624750053, 255), 8), 36), 2), 64)', 853624750053, True, fs('00000000 00000000 00000000 11000110 10111111 11111111 11111111 11100101'));

  Test({LINENUM}2353, 'SetMinLength(SetDigitGrouping(SetNumberBase(0, 10), 3), 10)', 0, True, fs('0 000 000 000'));
  Test({LINENUM}2354, 'SetMinLength(SetDigitGrouping(SetNumberBase(0, 16), 2), 8)', 0, True, fs('00 00 00 00'));
  Test({LINENUM}2355, 'SetMinLength(SetDigitGrouping(SetNumberBase(0, 2), 8), 32)', 0, True, fs('00000000 00000000 00000000 00000000'));
  Test({LINENUM}2356, 'SetMinLength(SetDigitGrouping(SetNumberBase(0, 2), 4), 32)', 0, True, fs('0000 0000 0000 0000 0000 0000 0000 0000'));


  //
  // Rational numbers (and the division operator on integers, and operators on rationals)
  //

  Test({LINENUM}2363, '1/2', Rat(1, 2), True, '1/2');
  Test({LINENUM}2364, '1/3', Rat(1, 3), True, '1/3');
  Test({LINENUM}2365, '1/1000000', Rat(1, 1000000), True, '1/1000000');
  Test({LINENUM}2366, '1237/17', Rat(1237, 17), True, '1237/17');
  Test({LINENUM}2367, '1237/1238', Rat(1237, 1238), True, '1237/1238');

  Test({LINENUM}2369, '-1/2', Rat(-1, 2), True, MINUS_SIGN + '1/2');
  Test({LINENUM}2370, '-1/3', Rat(-1, 3), True, MINUS_SIGN + '1/3');
  Test({LINENUM}2371, '-1/1000000', Rat(-1, 1000000), True, MINUS_SIGN + '1/1000000');
  Test({LINENUM}2372, '-1237/17', Rat(-1237, 17), True, MINUS_SIGN + '1237/17');
  Test({LINENUM}2373, '-1237/1238', Rat(-1237, 1238), True, MINUS_SIGN + '1237/1238');

  Test({LINENUM}2375, '1/1', 1, True, '1');
  Test({LINENUM}2376, '2/2', 1, True, '1');
  Test({LINENUM}2377, '987654321/987654321', 1, True, '1');
  Test({LINENUM}2378, '987654320/987654321', Rat(987654320, 987654321), True, '987654320/987654321');

  Test({LINENUM}2380, '-1/1', -1, True, MINUS_SIGN + '1');
  Test({LINENUM}2381, '-2/2', -1, True, MINUS_SIGN + '1');
  Test({LINENUM}2382, '-987654321/987654321', -1, True, MINUS_SIGN + '1');
  Test({LINENUM}2383, '-987654320/987654321', Rat(-987654320, 987654321), True, MINUS_SIGN + '987654320/987654321');

  Test({LINENUM}2385, '0/2', 0, True, '0');
  Test({LINENUM}2386, '0/3', 0, True, '0');
  Test({LINENUM}2387, '0/1000000', 0, True, '0');
  Test({LINENUM}2388, '0/17', 0, True, '0');
  Test({LINENUM}2389, '0/1238', 0, True, '0');

  Test({LINENUM}2391, '4/20', Rat(1, 5), True, '1/5');
  Test({LINENUM}2392, '40/200', Rat(1, 5), True, '1/5');
  Test({LINENUM}2393, '400000000/2000000000', Rat(1, 5), True, '1/5');
  Test({LINENUM}2394, '40000000000000/200000000000000', Rat(1, 5), True, '1/5');

  Test({LINENUM}2396, '-4/20', Rat(-1, 5), True, MINUS_SIGN + '1/5');
  Test({LINENUM}2397, '-40/200', Rat(-1, 5), True, MINUS_SIGN + '1/5');
  Test({LINENUM}2398, '-400000000/2000000000', Rat(-1, 5), True, MINUS_SIGN + '1/5');
  Test({LINENUM}2399, '-40000000000000/200000000000000', Rat(-1, 5), True, MINUS_SIGN + '1/5');

  Test({LINENUM}2401, '83250/47250', Rat(37, 21), True, '37/21');

  Test({LINENUM}2403, '1/3 + 1/4', Rat(7, 12), True, '7/12');
  Test({LINENUM}2404, '1/3 - 1/4', Rat(1, 12), True, '1/12');
  Test({LINENUM}2405, '(1/3) ⋅ (1/4)', Rat(1, 12), True, '1/12');
  Test({LINENUM}2406, '(7/3) ⋅ (3/4)', Rat(7, 4), True, '7/4');
  Test({LINENUM}2407, '(7/3) ⋅ (5/4)', Rat(35, 12), True, '35/12');
  Test({LINENUM}2408, '(7/3) / (3/4)', Rat(28, 9), True, '28/9');
  Test({LINENUM}2409, '(7/3) / (5/4)', Rat(28, 15), True, '28/15');

  Test({LINENUM}2411, '1/3 ⋅ 1/4', Rat(1, 12), True, '1/12');
  Test({LINENUM}2412, '7/3 ⋅ 3/4', Rat(7, 4), True, '7/4');
  Test({LINENUM}2413, '7/3 ⋅ 5/4', Rat(35, 12), True, '35/12');

  Test({LINENUM}2415, '(7/3) / (7/4)', Rat(4, 3), True, '4/3');
  Test({LINENUM}2416, '-(7/3) / (7/4)', Rat(-4, 3), True, MINUS_SIGN + '4/3');
  Test({LINENUM}2417, '(-7/3) / (7/4)', Rat(-4, 3), True, MINUS_SIGN + '4/3');
  Test({LINENUM}2418, '(7/-3) / (7/4)', Rat(-4, 3), True, MINUS_SIGN + '4/3');
  Test({LINENUM}2419, '(7/3) / -(7/4)', Rat(-4, 3), True, MINUS_SIGN + '4/3');
  Test({LINENUM}2420, '(7/3) / (-7/4)', Rat(-4, 3), True, MINUS_SIGN + '4/3');
  Test({LINENUM}2421, '(7/3) / (7/-4)', Rat(-4, 3), True, MINUS_SIGN + '4/3');
  Test({LINENUM}2422, '-(-7/-3) / -(-7/-4)', Rat(4, 3), True, '4/3');
  Test({LINENUM}2423, '--(-7/-3) / -(-7/-4)', Rat(-4, 3), True, MINUS_SIGN + '4/3');
  Test({LINENUM}2424, '-(-(-7/-3) / -(-7/-4))', Rat(-4, 3), True, MINUS_SIGN + '4/3');

  Test({LINENUM}2426, '0/3 + 1/4', Rat(1, 4), True, '1/4');
  Test({LINENUM}2427, '0 + 1/4', Rat(1, 4), True, '1/4');
  Test({LINENUM}2428, '(0/3) ⋅ (1/4)', Rat(0, 1), True, '0');
  Test({LINENUM}2429, '0 ⋅ (1/4)', Rat(0, 1), True, '0');

  Test({LINENUM}2431, '1/7 + 5', Rat(36, 7), True, '36/7');
  Test({LINENUM}2432, '1/7 - 5', Rat(-34, 7), True, MINUS_SIGN + '34/7');

  Test({LINENUM}2434, '5 + 1/7', Rat(36, 7), True, '36/7');
  Test({LINENUM}2435, '5 - 1/7', Rat(34, 7), True, '34/7');

  Test({LINENUM}2437, '5 ⋅ 1/7', Rat(5, 7), True, '5/7');
  Test({LINENUM}2438, '(5 ⋅ 1)/7', Rat(5, 7), True, '5/7');
  Test({LINENUM}2439, '5 ⋅ (1/7)', Rat(5, 7), True, '5/7');

  Test({LINENUM}2441, '123456789123456789/123456789123456', Rat(41152263041152263, 41152263041152), True, '41152263041152263/41152263041152');
  Test({LINENUM}2442, '-123456789123456789/123456789123456', Rat(-41152263041152263, 41152263041152), True, MINUS_SIGN + '41152263041152263/41152263041152');
  Test({LINENUM}2443, '123456789123456789/-123456789123456', Rat(-41152263041152263, 41152263041152), True, MINUS_SIGN + '41152263041152263/41152263041152');
  Test({LINENUM}2444, '-123456789123456789/--123456789123456', Rat(-41152263041152263, 41152263041152), True, MINUS_SIGN + '41152263041152263/41152263041152');
  Test({LINENUM}2445, '-(-(---123456789123456789/--123456789123456))', Rat(-41152263041152263, 41152263041152), True, MINUS_SIGN + '41152263041152263/41152263041152');
  Test({LINENUM}2446, '-(-(---123456789123456789/-(--123456789123456)))', Rat(41152263041152263, 41152263041152), True, '41152263041152263/41152263041152');

  Test({LINENUM}2448, '9223372036854775807/9223372036854775807', 1, True, '1');
  Test({LINENUM}2449, '9223372036854775806/9223372036854775807', Rat(9223372036854775806, 9223372036854775807), True, '9223372036854775806/9223372036854775807');

  Test({LINENUM}2451, '-9223372036854775807/9223372036854775807', -1, True, MINUS_SIGN + '1');
  Test({LINENUM}2452, '-9223372036854775806/9223372036854775807', Rat(-9223372036854775806, 9223372036854775807), True, MINUS_SIGN + '9223372036854775806/9223372036854775807');

  Test({LINENUM}2454, '1/357 + 512/879 - 12/67 + 22/17', Rat(3972039, 2336089), True, '3972039/2336089');
  Test({LINENUM}2455, '52/75 + 94/73 - 12/85 + 6523/51 + 152/7', Rat(32892473, 217175), True, '32892473/217175');
  Test({LINENUM}2456, '2/84 - 8563/1 + 5892/7 - 2/9853', Rat(-3195259013, 413826), True, MINUS_SIGN + '3195259013/413826');
  Test({LINENUM}2457, '532/751 + 9583/9571 - 9856/8522 + 3/7 - 89/2', Rat(-18659885062139, 428782273934), True, MINUS_SIGN + '18659885062139/428782273934');
  Test({LINENUM}2458, '15236/8562712 + 9/2', Rat(4818430, 1070339), True, '4818430/1070339');
  Test({LINENUM}2459, '21/5784632 - 8/3', Rat(-6610999, 2479128), True, MINUS_SIGN + '6610999/2479128');
  Test({LINENUM}2460, '2/7 ⋅ 5/1 ⋅ 5/9 ⋅ 3/7 ⋅ 7/2 ⋅ 2/7 ⋅ 1/3 ⋅ 6/4 ⋅ 7/2 ⋅ 4/6 ⋅ 9/8 ⋅ 2/7 ⋅ 7/1 ⋅ 4/5 ⋅ 6/8', Rat(15, 28), True, '15/28');
  Test({LINENUM}2461, '2/7 ⋅ 5/1 ⋅ 5/9 ⋅ 3/7 ⋅ 7/2 ⋅ 2/7 ⋅ 1/3 ⋅ 6/0 ⋅ 7/2 ⋅ 4/6 ⋅ 9/8 ⋅ 2/7 ⋅ 7/1 ⋅ 4/5 ⋅ 6/8', failure, 'division by zero');
  Test({LINENUM}2462, '598 ⋅ 752/411856', Rat(28106, 25741), True, '28106/25741');
  Test({LINENUM}2463, '752/411856 ⋅ 598', Rat(28106, 25741), True, '28106/25741');
  Test({LINENUM}2464, '0 ⋅ 752/411856', 0, True, '0');
  Test({LINENUM}2465, '0 ⋅ (752/411856)', Rat(0, 1), True, '0');

//  Test({LINENUM}2467, '9223372036854775806/9223372036854775807 + 1/9223372036854775807', Rat(1, 1), True, '1');

  Test({LINENUM}2469, 'SetNumberBase(SetMinLength(SetDigitGrouping(255/256, 2), 8), 16)', Rat(255, 256), True, fs('00 00 00 FF/00 00 01 00'));


  //
  // Real numbers
  //

  Test({LINENUM}2476, '3.1415', 3.1415, True, '3.1415');
  Test({LINENUM}2477, '-3.1415', -3.1415, True, MINUS_SIGN + '3.1415');

  Test({LINENUM}2479, '3.141592653589793238', 3.141592653589793238, True, '3.14159265359');
  Test({LINENUM}2480, '-3.141592653589793238', -3.141592653589793238, True, MINUS_SIGN + '3.14159265359');

  Test({LINENUM}2482, '3', 3, True, '3');
  Test({LINENUM}2483, '3.', 3.0, True, '3');

  Test({LINENUM}2485, '-3', -3, True, MINUS_SIGN + '3');
  Test({LINENUM}2486, '-3.', -3.0, True, MINUS_SIGN + '3');

  Test({LINENUM}2488, '.1415', 0.1415, True, '0.1415');
  Test({LINENUM}2489, '-.1415', -0.1415, True, MINUS_SIGN + '0.1415');

  Test({LINENUM}2491, '.', 0.0, True, '0');
  Test({LINENUM}2492, '+.', 0.0, True, '0');
  Test({LINENUM}2493, '-.', 0.0, True, '0');
  Test({LINENUM}2494, '.+.', 0.0, True, '0');

  Test({LINENUM}2496, '123456.789', 123456.789, True, '123456.789');
  Test({LINENUM}2497, '-123456.789', -123456.789, True, MINUS_SIGN + '123456.789');

  Test({LINENUM}2499, '1/2', Rat(1, 2), True, '1/2');
  Test({LINENUM}2500, '1./2', 0.5, True, '0.5');
  Test({LINENUM}2501, '1/2.', 0.5, True, '0.5');

  Test({LINENUM}2503, '1/3', Rat(1, 3), True, '1/3');
  Test({LINENUM}2504, '1./3', 1/3, True, '0.333333333333');
  Test({LINENUM}2505, '1/3.', 1/3, True, '0.333333333333');

  Test({LINENUM}2507, '-1/2', Rat(-1, 2), True, MINUS_SIGN + '1/2');
  Test({LINENUM}2508, '-1./2', -0.5, True, MINUS_SIGN + '0.5');
  Test({LINENUM}2509, '-1/2.', -0.5, True, MINUS_SIGN + '0.5');

  Test({LINENUM}2511, '-1/3', Rat(-1, 3), True, MINUS_SIGN + '1/3');
  Test({LINENUM}2512, '-1./3', -1/3, True, MINUS_SIGN + '0.333333333333');
  Test({LINENUM}2513, '-1/3.', -1/3, True, MINUS_SIGN + '0.333333333333');

  // Format: default, number of digits

  Test({LINENUM}2517, '1./3', 1/3, True, '0.333333333333');
  Test({LINENUM}2518, '1./3 \ 2', 1/3, True, '0.33');
  Test({LINENUM}2519, '1./3 \ 3', 1/3, True, '0.333');
  Test({LINENUM}2520, '1./3 \ 4', 1/3, True, '0.3333');
  Test({LINENUM}2521, '1./3 \ 5', 1/3, True, '0.33333');
  Test({LINENUM}2522, '1./3 \ 12', 1/3, True, '0.333333333333');
  Test({LINENUM}2523, '1./3 \ 16', 1/3, True, '0.3333333333333333');

  Test({LINENUM}2525, '-1./3', -1/3, True, MINUS_SIGN + '0.333333333333');
  Test({LINENUM}2526, '-1./3 \ 2', -1/3, True, MINUS_SIGN + '0.33');
  Test({LINENUM}2527, '-1./3 \ 3', -1/3, True, MINUS_SIGN + '0.333');
  Test({LINENUM}2528, '-1./3 \ 4', -1/3, True, MINUS_SIGN + '0.3333');
  Test({LINENUM}2529, '-1./3 \ 5', -1/3, True, MINUS_SIGN + '0.33333');
  Test({LINENUM}2530, '-1./3 \ 12', -1/3, True, MINUS_SIGN + '0.333333333333');
  Test({LINENUM}2531, '-1./3 \ 16', -1/3, True, MINUS_SIGN + '0.3333333333333333');

  Test({LINENUM}2533, '1./3', 1/3, True, '0.333333333333'); // operator \ maps to SetMaxLen
  Test({LINENUM}2534, 'SetMaxLen(1./3, 2)', 1/3, True, '0.33');
  Test({LINENUM}2535, 'SetMaxLen(1./3, 3)', 1/3, True, '0.333');
  Test({LINENUM}2536, 'SetMaxLen(1./3, 4)', 1/3, True, '0.3333');
  Test({LINENUM}2537, 'SetMaxLen(1./3, 5)', 1/3, True, '0.33333');
  Test({LINENUM}2538, 'SetMaxLen(1./3, 12)', 1/3, True, '0.333333333333');
  Test({LINENUM}2539, 'SetMaxLen(1./3, 16)', 1/3, True, '0.3333333333333333');

  Test({LINENUM}2541, '-1./3', -1/3, True, MINUS_SIGN + '0.333333333333');
  Test({LINENUM}2542, 'SetMaxLen(-1./3, 2)', -1/3, True, MINUS_SIGN + '0.33');
  Test({LINENUM}2543, 'SetMaxLen(-1./3, 3)', -1/3, True, MINUS_SIGN + '0.333');
  Test({LINENUM}2544, 'SetMaxLen(-1./3, 4)', -1/3, True, MINUS_SIGN + '0.3333');
  Test({LINENUM}2545, 'SetMaxLen(-1./3, 5)', -1/3, True, MINUS_SIGN + '0.33333');
  Test({LINENUM}2546, 'SetMaxLen(-1./3, 12)', -1/3, True, MINUS_SIGN + '0.333333333333');
  Test({LINENUM}2547, 'SetMaxLen(-1./3, 16)', -1/3, True, MINUS_SIGN + '0.3333333333333333');

  Test({LINENUM}2549, '1./3', 1/3, True, '0.333333333333'); // SetMaxLen works like SetNumDigits when arg 1 is a number and arg 2 is >= 0
  Test({LINENUM}2550, 'SetNumDigits(1./3, 2)', 1/3, True, '0.33');
  Test({LINENUM}2551, 'SetNumDigits(1./3, 3)', 1/3, True, '0.333');
  Test({LINENUM}2552, 'SetNumDigits(1./3, 4)', 1/3, True, '0.3333');
  Test({LINENUM}2553, 'SetNumDigits(1./3, 5)', 1/3, True, '0.33333');
  Test({LINENUM}2554, 'SetNumDigits(1./3, 12)', 1/3, True, '0.333333333333');
  Test({LINENUM}2555, 'SetNumDigits(1./3, 16)', 1/3, True, '0.3333333333333333');

  Test({LINENUM}2557, '-1./3', -1/3, True, MINUS_SIGN + '0.333333333333');
  Test({LINENUM}2558, 'SetNumDigits(-1./3, 2)', -1/3, True, MINUS_SIGN + '0.33');
  Test({LINENUM}2559, 'SetNumDigits(-1./3, 3)', -1/3, True, MINUS_SIGN + '0.333');
  Test({LINENUM}2560, 'SetNumDigits(-1./3, 4)', -1/3, True, MINUS_SIGN + '0.3333');
  Test({LINENUM}2561, 'SetNumDigits(-1./3, 5)', -1/3, True, MINUS_SIGN + '0.33333');
  Test({LINENUM}2562, 'SetNumDigits(-1./3, 12)', -1/3, True, MINUS_SIGN + '0.333333333333');
  Test({LINENUM}2563, 'SetNumDigits(-1./3, 16)', -1/3, True, MINUS_SIGN + '0.3333333333333333');

  Test({LINENUM}2565, 'SetNumDigits(1./3, -1)', 1/3, True, '0.333333333333'); // SetNumDigits: negative count means inherit
  Test({LINENUM}2566, 'SetMaxLen(1./3, -1)', failure, 'A non-negative integer was expected as argument 2, but "-1" was given.'); // SetMaxLength requires a non-negative second argument
  Test({LINENUM}2567, '1./3 \ -1', failure, 'A non-negative integer was expected as argument 2, but "-1" was given.'); // SetMaxLength requires a non-negative second argument

  Test({LINENUM}2569, 'SetNumDigits(1./3, "a")', failure, 'An object of type integer was expected as argument 2, but an object of type string was given.');
  Test({LINENUM}2570, 'SetMaxLen(1./3, "a")', failure, 'An object of type integer was expected as argument 2, but an object of type string was given.');
  Test({LINENUM}2571, '1./3 \ "a"', failure, 'An object of type integer was expected as argument 2, but an object of type string was given.');

  Test({LINENUM}2573, 'SetNumDigits(1./3, 6, 10)', failure, 'Too many arguments.');
  Test({LINENUM}2574, 'SetNumDigits(1./3)', failure, 'Too few arguments. A required argument of type integer is missing.');

  Test({LINENUM}2576, '2./3', 2/3, True, '0.666666666667');
  Test({LINENUM}2577, '2./3 \ 2', 2/3, True, '0.67');
  Test({LINENUM}2578, '2./3 \ 3', 2/3, True, '0.667');
  Test({LINENUM}2579, '2./3 \ 4', 2/3, True, '0.6667');
  Test({LINENUM}2580, '2./3 \ 5', 2/3, True, '0.66667');
  Test({LINENUM}2581, '2./3 \ 12', 2/3, True, '0.666666666667');
  Test({LINENUM}2582, '2./3 \ 16', 2/3, True, '0.6666666666666667');

  Test({LINENUM}2584, '-2./3', -2/3, True, MINUS_SIGN + '0.666666666667');
  Test({LINENUM}2585, '-2./3 \ 2', -2/3, True, MINUS_SIGN + '0.67');
  Test({LINENUM}2586, '-2./3 \ 3', -2/3, True, MINUS_SIGN + '0.667');
  Test({LINENUM}2587, '-2./3 \ 4', -2/3, True, MINUS_SIGN + '0.6667');
  Test({LINENUM}2588, '-2./3 \ 5', -2/3, True, MINUS_SIGN + '0.66667');
  Test({LINENUM}2589, '-2./3 \ 12', -2/3, True, MINUS_SIGN + '0.666666666667');
  Test({LINENUM}2590, '-2./3 \ 16', -2/3, True, MINUS_SIGN + '0.6666666666666667');

  // Exp literals and default format's exp notation

  Test({LINENUM}2594, '7E20', 7E20, True, mm('7*10^20'));
  Test({LINENUM}2595, '1E20 + 7E20', 8E20, True, mm('8*10^20'));
  Test({LINENUM}2596, '7E-20', 7E-20, True, mm('7*10^-20'));
  Eps; Test({LINENUM}2597, '1E-20 + 7E-20', 8E-20, True, mm('8*10^-20'));
  Test({LINENUM}2598, '123.45E20', 123.45E20, True, mm('1.2345*10^22'));
  Test({LINENUM}2599, '123.45E-20', 123.45E-20, True, mm('1.2345*10^-18'));
  Test({LINENUM}2600, '-123.45E20', -123.45E20, True, mm('-1.2345*10^22'));
  Test({LINENUM}2601, '-123.45E-20', -123.45E-20, True, mm('-1.2345*10^-18'));
  Test({LINENUM}2602, '3E3 + 2E2 + 1E1 + 0E0 + 1E-1 + 2E-2 + 3E-3', 3210.123, True, mm('3210.123'));
  Test({LINENUM}2603, '-3E3 - 2E2 - 1E1 - 0E0 - 1E-1 - 2E-2 - 3E-3', -3210.123, True, mm('-3210.123'));
  Test({LINENUM}2604, '1E0', 1.0, True, '1');
  Test({LINENUM}2605, '7E0', 7.0, True, '7');
  Test({LINENUM}2606, '123456.123456E0', 123456.123456, True, '123456.123456');
  Test({LINENUM}2607, '-123456.123456E0', -123456.123456, True, MINUS_SIGN + '123456.123456');
  Test({LINENUM}2608, '12300000000000000000000000000000000000000000', 1.23E43, True, mm('1.23*10^43'));
  Test({LINENUM}2609, '-12300000000000000000000000000000000000000000', -1.23E43, True, mm('-1.23*10^43'));
  Test({LINENUM}2610, '0.0000000000000000000123', 1.23E-20, True, mm('1.23*10^-20'));
  Test({LINENUM}2611, '-0.0000000000000000000123', -1.23E-20, True, mm('-1.23*10^-20'));
  Test({LINENUM}2612, '1E20', 1E20, True, mm('1*10^20')); // a future version might skip the "1*" part
  Test({LINENUM}2613, '1E-20', 1E-20, True, mm('1*10^-20')); // -"-

  Test({LINENUM}2615, '123456.', 123456.0, True, '123456');
  Test({LINENUM}2616, '123456. \ 8', 123456.0, True, '123456');
  Test({LINENUM}2617, '123456. \ 6', 123456.0, True, '123456');
  Test({LINENUM}2618, '123456. \ 5', 123456.0, True, mm('1.2346*10^5'));
  Test({LINENUM}2619, '123456. \ 4', 123456.0, True, mm('1.235*10^5'));
  Test({LINENUM}2620, '123456. \ 3', 123456.0, True, mm('1.23*10^5'));
  Test({LINENUM}2621, '123456. \ 2', 123456.0, True, mm('1.2*10^5'));

  Test({LINENUM}2623, '-123456.', -123456.0, True, MINUS_SIGN + '123456');
  Test({LINENUM}2624, '-123456. \ 8', -123456.0, True, MINUS_SIGN + '123456');
  Test({LINENUM}2625, '-123456. \ 6', -123456.0, True, MINUS_SIGN + '123456');
  Test({LINENUM}2626, '-123456. \ 5', -123456.0, True, mm('-1.2346*10^5'));
  Test({LINENUM}2627, '-123456. \ 4', -123456.0, True, mm('-1.235*10^5'));
  Test({LINENUM}2628, '-123456. \ 3', -123456.0, True, mm('-1.23*10^5'));
  Test({LINENUM}2629, '-123456. \ 2', -123456.0, True, mm('-1.2*10^5'));

  // Format: default, pretty exp notation

  Test({LINENUM}2633, '7E20', 7E20, True, mm('7*10^20'));
  Test({LINENUM}2634, 'SetPrettyExp(7E20, true)', 7E20, True, mm('7*10^20'));
  Test({LINENUM}2635, 'SetPrettyExp(7E20, false)', 7E20, True, mm('7E20'));

  Test({LINENUM}2637, '7E-20', 7E-20, True, mm('7*10^-20'));
  Test({LINENUM}2638, 'SetPrettyExp(7E-20, true)', 7E-20, True, mm('7*10^-20'));
  Test({LINENUM}2639, 'SetPrettyExp(7E-20, false)', 7E-20, True, mm('7E-20'));

  Test({LINENUM}2641, '-7E20', -7E20, True, mm('-7*10^20'));
  Test({LINENUM}2642, 'SetPrettyExp(-7E20, true)', -7E20, True, mm('-7*10^20'));
  Test({LINENUM}2643, 'SetPrettyExp(-7E20, false)', -7E20, True, mm('-7E20'));

  Test({LINENUM}2645, '-7E-20', -7E-20, True, mm('-7*10^-20'));
  Test({LINENUM}2646, 'SetPrettyExp(-7E-20, true)', -7E-20, True, mm('-7*10^-20'));
  Test({LINENUM}2647, 'SetPrettyExp(-7E-20, false)', -7E-20, True, mm('-7E-20'));

  Test({LINENUM}2649, '-123456. \ 2', -123456.0, True, mm('-1.2*10^5'));
  Test({LINENUM}2650, 'SetPrettyExp(-123456., true) \ 2', -123456.0, True, mm('-1.2*10^5'));
  Test({LINENUM}2651, 'SetPrettyExp(-123456., false) \ 2', -123456.0, True, mm('-1.2E5'));
  Test({LINENUM}2652, 'SetPrettyExp(-123456. \ 2, false)', -123456.0, True, mm('-1.2E5'));

  Test({LINENUM}2654, 'SetPrettyExp(7E20, 7)', failure, 'An object of type boolean was expected as argument 2, but an object of type integer was given.');
  Test({LINENUM}2655, 'SetPrettyExp(7E20)', failure, 'Too few arguments. A required argument of type boolean is missing.');
  Test({LINENUM}2656, 'SetPrettyExp(7E20, true, 2)', failure, 'Too many arguments.');

  // Format: fixed, number of digits

  Test({LINENUM}2660, '123.45678', 123.45678, True, '123.45678');
  Test({LINENUM}2661, 'SetNumberFormat(123.45678, "inherited")', 123.45678, True, '123.45678');
  Test({LINENUM}2662, 'SetNumberFormat(123.45678, "default")', 123.45678, True, '123.45678');
  Test({LINENUM}2663, 'SetNumberFormat(123.45678, "fixed")', 123.45678, True, '123.456780000000');
  Test({LINENUM}2664, 'SetNumberFormat(123.45678, "fixed") \ 10', 123.45678, True, '123.4567800000');
  Test({LINENUM}2665, 'SetNumberFormat(123.45678, "fixed") \ 8', 123.45678, True, '123.45678000');
  Test({LINENUM}2666, 'SetNumberFormat(123.45678, "fixed") \ 6', 123.45678, True, '123.456780');
  Test({LINENUM}2667, 'SetNumberFormat(123.45678, "fixed") \ 3', 123.45678, True, '123.457');
  Test({LINENUM}2668, 'SetNumberFormat(123.45678, "fixed") \ 2', 123.45678, True, '123.46');
  Test({LINENUM}2669, 'SetNumberFormat(123.45678, "fixed") \ 1', 123.45678, True, '123.5');
  Test({LINENUM}2670, 'SetNumberFormat(123.45678, "fixed") \ 0', 123.45678, True, '123');

  Test({LINENUM}2672, 'SetNumberFormat(123.45678, "default") \ 10', 123.45678, True, '123.45678');
  Test({LINENUM}2673, 'SetNumberFormat(123.45678, "default") \ 8', 123.45678, True, '123.45678');
  Test({LINENUM}2674, 'SetNumberFormat(123.45678, "default") \ 6', 123.45678, True, '123.457');
  Test({LINENUM}2675, 'SetNumberFormat(123.45678, "default") \ 3', 123.45678, True, '123');
  Test({LINENUM}2676, 'SetNumberFormat(123.45678, "default") \ 2', 123.45678, True, mm('1.2*10^2'));

  Test({LINENUM}2678, '-123.45678', -123.45678, True, MINUS_SIGN + '123.45678');
  Test({LINENUM}2679, 'SetNumberFormat(-123.45678, "inherited")', -123.45678, True, MINUS_SIGN + '123.45678');
  Test({LINENUM}2680, 'SetNumberFormat(-123.45678, "default")', -123.45678, True, MINUS_SIGN + '123.45678');
  Test({LINENUM}2681, 'SetNumberFormat(-123.45678, "fixed")', -123.45678, True, MINUS_SIGN + '123.456780000000');
  Test({LINENUM}2682, 'SetNumberFormat(-123.45678, "fixed") \ 10', -123.45678, True, MINUS_SIGN + '123.4567800000');
  Test({LINENUM}2683, 'SetNumberFormat(-123.45678, "fixed") \ 8', -123.45678, True, MINUS_SIGN + '123.45678000');
  Test({LINENUM}2684, 'SetNumberFormat(-123.45678, "fixed") \ 6', -123.45678, True, MINUS_SIGN + '123.456780');
  Test({LINENUM}2685, 'SetNumberFormat(-123.45678, "fixed") \ 3', -123.45678, True, MINUS_SIGN + '123.457');
  Test({LINENUM}2686, 'SetNumberFormat(-123.45678, "fixed") \ 2', -123.45678, True, MINUS_SIGN + '123.46');
  Test({LINENUM}2687, 'SetNumberFormat(-123.45678, "fixed") \ 1', -123.45678, True, MINUS_SIGN + '123.5');
  Test({LINENUM}2688, 'SetNumberFormat(-123.45678, "fixed") \ 0', -123.45678, True, MINUS_SIGN + '123');

  Test({LINENUM}2690, 'SetNumberFormat(-123.45678, "default") \ 10', -123.45678, True, MINUS_SIGN + '123.45678');
  Test({LINENUM}2691, 'SetNumberFormat(-123.45678, "default") \ 8', -123.45678, True, MINUS_SIGN + '123.45678');
  Test({LINENUM}2692, 'SetNumberFormat(-123.45678, "default") \ 6', -123.45678, True, MINUS_SIGN + '123.457');
  Test({LINENUM}2693, 'SetNumberFormat(-123.45678, "default") \ 3', -123.45678, True, MINUS_SIGN + '123');
  Test({LINENUM}2694, 'SetNumberFormat(-123.45678, "default") \ 2', -123.45678, True, mm('-1.2*10^2'));

  // Format: fixed, large and small numbers

  Test({LINENUM}2698, 'SetNumberFormat(123.456E20, "fixed")', 123.456E20, True, mm('1.23456*10^22')); // reasonable to give up "fixed"
  Test({LINENUM}2699, 'SetNumberFormat(-123.456E20, "fixed")', -123.456E20, True, mm('-1.23456*10^22'));

  Test({LINENUM}2701, 'SetNumberFormat(123.456E-20, "fixed") \ 10', 123.456E-20, True, mm('0.0000000000')); // obvious
  Test({LINENUM}2702, 'SetNumberFormat(-123.456E-20, "fixed") \ 10', -123.456E-20, True, mm('0.0000000000'));

  // Format: scientific

  Test({LINENUM}2706, '123.4567', 123.4567, True, '123.4567');
  Test({LINENUM}2707, 'SetNumberFormat(123.4567, "default") \ 10', 123.4567, True, mm('123.4567'));
  Test({LINENUM}2708, 'SetNumberFormat(123.4567, "fixed") \ 10', 123.4567, True, mm('123.4567000000'));
  Test({LINENUM}2709, 'SetNumberFormat(123.4567, "scientific") \ 10', 123.4567, True, mm('1.234567000*10^2'));

  Test({LINENUM}2711, 'SetNumberFormat(123.4567, "default") \ 8', 123.4567, True, mm('123.4567'));
  Test({LINENUM}2712, 'SetNumberFormat(123.4567, "fixed") \ 8', 123.4567, True, mm('123.45670000'));
  Test({LINENUM}2713, 'SetNumberFormat(123.4567, "scientific") \ 8', 123.4567, True, mm('1.2345670*10^2'));

  Test({LINENUM}2715, 'SetNumberFormat(123.4567, "default") \ 6', 123.4567, True, mm('123.457'));
  Test({LINENUM}2716, 'SetNumberFormat(123.4567, "fixed") \ 6', 123.4567, True, mm('123.456700'));
  Test({LINENUM}2717, 'SetNumberFormat(123.4567, "scientific") \ 6', 123.4567, True, mm('1.23457*10^2'));

  Test({LINENUM}2719, 'SetNumberFormat(123.4567, "default") \ 4', 123.4567, True, mm('123.5'));
  Test({LINENUM}2720, 'SetNumberFormat(123.4567, "fixed") \ 4', 123.4567, True, mm('123.4567'));
  Test({LINENUM}2721, 'SetNumberFormat(123.4567, "scientific") \ 4', 123.4567, True, mm('1.235*10^2'));

  Test({LINENUM}2723, 'SetNumberFormat(123.4567, "default") \ 2', 123.4567, True, mm('1.2*10^2'));
  Test({LINENUM}2724, 'SetNumberFormat(123.4567, "fixed") \ 2', 123.4567, True, mm('123.46'));
  Test({LINENUM}2725, 'SetNumberFormat(123.4567, "scientific") \ 2', 123.4567, True, mm('1.2*10^2'));

  Test({LINENUM}2727, '-123.4567', -123.4567, True, MINUS_SIGN + '123.4567');
  Test({LINENUM}2728, 'SetNumberFormat(-123.4567, "default") \ 10', -123.4567, True, mm('-123.4567'));
  Test({LINENUM}2729, 'SetNumberFormat(-123.4567, "fixed") \ 10', -123.4567, True, mm('-123.4567000000'));
  Test({LINENUM}2730, 'SetNumberFormat(-123.4567, "scientific") \ 10', -123.4567, True, mm('-1.234567000*10^2'));

  Test({LINENUM}2732, 'SetNumberFormat(-123.4567, "default") \ 8', -123.4567, True, mm('-123.4567'));
  Test({LINENUM}2733, 'SetNumberFormat(-123.4567, "fixed") \ 8', -123.4567, True, mm('-123.45670000'));
  Test({LINENUM}2734, 'SetNumberFormat(-123.4567, "scientific") \ 8', -123.4567, True, mm('-1.2345670*10^2'));

  Test({LINENUM}2736, 'SetNumberFormat(-123.4567, "default") \ 6', -123.4567, True, mm('-123.457'));
  Test({LINENUM}2737, 'SetNumberFormat(-123.4567, "fixed") \ 6', -123.4567, True, mm('-123.456700'));
  Test({LINENUM}2738, 'SetNumberFormat(-123.4567, "scientific") \ 6', -123.4567, True, mm('-1.23457*10^2'));

  Test({LINENUM}2740, 'SetNumberFormat(-123.4567, "default") \ 4', -123.4567, True, mm('-123.5'));
  Test({LINENUM}2741, 'SetNumberFormat(-123.4567, "fixed") \ 4', -123.4567, True, mm('-123.4567'));
  Test({LINENUM}2742, 'SetNumberFormat(-123.4567, "scientific") \ 4', -123.4567, True, mm('-1.235*10^2'));

  Test({LINENUM}2744, 'SetNumberFormat(-123.4567, "default") \ 2', -123.4567, True, mm('-1.2*10^2'));
  Test({LINENUM}2745, 'SetNumberFormat(-123.4567, "fixed") \ 2', -123.4567, True, mm('-123.46'));
  Test({LINENUM}2746, 'SetNumberFormat(-123.4567, "scientific") \ 2', -123.4567, True, mm('-1.2*10^2'));

  // Format: scientific, pretty exp off

  Test({LINENUM}2750, 'SetPrettyExp(SetNumberFormat(-123.4567, "default"), false) \ 2', -123.4567, True, mm('-1.2E2'));
  Test({LINENUM}2751, 'SetPrettyExp(SetNumberFormat(-123.4567, "fixed"), false) \ 2', -123.4567, True, mm('-123.46'));
  Test({LINENUM}2752, 'SetPrettyExp(SetNumberFormat(-123.4567, "scientific"), false) \ 2', -123.4567, True, mm('-1.2E+2'));

  Test({LINENUM}2754, 'SetPrettyExp(1E20, false)', 1E20, True, '1E20');
  Test({LINENUM}2755, 'SetPrettyExp(SetNumberFormat(1E20, "default") \ 4, false)', 1E20, True, '1E20');
  Test({LINENUM}2756, 'SetPrettyExp(SetNumberFormat(1E20, "scientific") \ 4, false)', 1E20, True, '1.000E+20');

  Test({LINENUM}2758, 'SetPrettyExp(-1E20, false)', -1E20, True, mm('-1E20'));
  Test({LINENUM}2759, 'SetPrettyExp(SetNumberFormat(-1E20, "default") \ 4, false)', -1E20, True, mm('-1E20'));
  Test({LINENUM}2760, 'SetPrettyExp(SetNumberFormat(-1E20, "scientific") \ 4, false)', -1E20, True, mm('-1.000E+20'));

  Test({LINENUM}2762, 'SetPrettyExp(1E-20, false)', 1E-20, True, mm('1E-20'));
  Test({LINENUM}2763, 'SetPrettyExp(SetNumberFormat(1E-20, "default") \ 4, false)', 1E-20, True, mm('1E-20'));
  Test({LINENUM}2764, 'SetPrettyExp(SetNumberFormat(1E-20, "scientific") \ 4, false)', 1E-20, True, mm('1.000E-20'));

  // Format: digit grouping (default style, no exps)

  Test({LINENUM}2768, 'SetDigitGrouping(123456.123456, -1)', 123456.123456, True, '123456.123456');
  Test({LINENUM}2769, 'SetDigitGrouping(123456.123456, 0)', 123456.123456, True, '123456.123456');
  Test({LINENUM}2770, 'SetDigitGrouping(123456.123456, 1)', 123456.123456, True, fs('1 2 3 4 5 6.1 2 3 4 5 6'));
  Test({LINENUM}2771, 'SetDigitGrouping(123456.123456, 2)', 123456.123456, True, fs('12 34 56.12 34 56'));
  Test({LINENUM}2772, 'SetDigitGrouping(123456.123456, 3)', 123456.123456, True, fs('123 456.123 456'));
  Test({LINENUM}2773, 'SetDigitGrouping(123456.123456, 4)', 123456.123456, True, fs('12 3456.1234 56'));
  Test({LINENUM}2774, 'SetDigitGrouping(123456.123456, 5)', 123456.123456, True, fs('1 23456.12345 6'));
  Test({LINENUM}2775, 'SetDigitGrouping(123456.123456, 6)', 123456.123456, True, fs('123456.123456'));
  Test({LINENUM}2776, 'SetDigitGrouping(123456.123456, 7)', 123456.123456, True, fs('123456.123456'));
  Test({LINENUM}2777, 'SetDigitGrouping(123456.123456, 8)', 123456.123456, True, fs('123456.123456'));

  Test({LINENUM}2779, 'SetDigitGrouping(-123456.123456, -1)', -123456.123456, True, MINUS_SIGN + '123456.123456');
  Test({LINENUM}2780, 'SetDigitGrouping(-123456.123456, 0)', -123456.123456, True, MINUS_SIGN + '123456.123456');
  Test({LINENUM}2781, 'SetDigitGrouping(-123456.123456, 1)', -123456.123456, True, MINUS_SIGN + fs('1 2 3 4 5 6.1 2 3 4 5 6'));
  Test({LINENUM}2782, 'SetDigitGrouping(-123456.123456, 2)', -123456.123456, True, MINUS_SIGN + fs('12 34 56.12 34 56'));
  Test({LINENUM}2783, 'SetDigitGrouping(-123456.123456, 3)', -123456.123456, True, MINUS_SIGN + fs('123 456.123 456'));
  Test({LINENUM}2784, 'SetDigitGrouping(-123456.123456, 4)', -123456.123456, True, MINUS_SIGN + fs('12 3456.1234 56'));
  Test({LINENUM}2785, 'SetDigitGrouping(-123456.123456, 5)', -123456.123456, True, MINUS_SIGN + fs('1 23456.12345 6'));
  Test({LINENUM}2786, 'SetDigitGrouping(-123456.123456, 6)', -123456.123456, True, MINUS_SIGN + fs('123456.123456'));
  Test({LINENUM}2787, 'SetDigitGrouping(-123456.123456, 7)', -123456.123456, True, MINUS_SIGN + fs('123456.123456'));
  Test({LINENUM}2788, 'SetDigitGrouping(-123456.123456, 8)', -123456.123456, True, MINUS_SIGN + fs('123456.123456'));

  // Format: digit grouping (default style, with exps)

  Test({LINENUM}2792, 'SetDigitGrouping(1.23456123456E20, -1)', 1.23456123456E20, True, mm(fs('1.23456123456*10^20')));
  Test({LINENUM}2793, 'SetDigitGrouping(1.23456123456E20, 0)', 1.23456123456E20, True, mm(fs('1.23456123456*10^20')));
  Test({LINENUM}2794, 'SetDigitGrouping(1.23456123456E20, 1)', 1.23456123456E20, True, mm(fs('1.2 3 4 5 6 1 2 3 4 5 6*10^20')));
  Test({LINENUM}2795, 'SetDigitGrouping(1.23456123456E20, 2)', 1.23456123456E20, True, mm(fs('1.23 45 61 23 45 6*10^20')));
  Test({LINENUM}2796, 'SetDigitGrouping(1.23456123456E20, 3)', 1.23456123456E20, True, mm(fs('1.234 561 234 56*10^20')));
  Test({LINENUM}2797, 'SetDigitGrouping(1.23456123456E20, 4)', 1.23456123456E20, True, mm(fs('1.2345 6123 456*10^20')));
  Test({LINENUM}2798, 'SetDigitGrouping(1.23456123456E20, 5)', 1.23456123456E20, True, mm(fs('1.23456 12345 6*10^20')));
  Test({LINENUM}2799, 'SetDigitGrouping(1.23456123456E20, 6)', 1.23456123456E20, True, mm(fs('1.234561 23456*10^20')));
  Test({LINENUM}2800, 'SetDigitGrouping(1.23456123456E20, 7)', 1.23456123456E20, True, mm(fs('1.2345612 3456*10^20')));
  Test({LINENUM}2801, 'SetDigitGrouping(1.23456123456E20, 8)', 1.23456123456E20, True, mm(fs('1.23456123 456*10^20')));
  Test({LINENUM}2802, 'SetDigitGrouping(1.23456123456E20, 9)', 1.23456123456E20, True, mm(fs('1.234561234 56*10^20')));
  Test({LINENUM}2803, 'SetDigitGrouping(1.23456123456E20, 10)', 1.23456123456E20, True, mm(fs('1.2345612345 6*10^20')));
  Test({LINENUM}2804, 'SetDigitGrouping(1.23456123456E20, 11)', 1.23456123456E20, True, mm(fs('1.23456123456*10^20')));
  Test({LINENUM}2805, 'SetDigitGrouping(1.23456123456E20, 12)', 1.23456123456E20, True, mm(fs('1.23456123456*10^20')));

  Test({LINENUM}2807, 'SetDigitGrouping(1.23456123456E-20, -1)', 1.23456123456E-20, True, mm(fs('1.23456123456*10^-20')));
  Test({LINENUM}2808, 'SetDigitGrouping(1.23456123456E-20, 0)', 1.23456123456E-20, True, mm(fs('1.23456123456*10^-20')));
  Test({LINENUM}2809, 'SetDigitGrouping(1.23456123456E-20, 1)', 1.23456123456E-20, True, mm(fs('1.2 3 4 5 6 1 2 3 4 5 6*10^-20')));
  Test({LINENUM}2810, 'SetDigitGrouping(1.23456123456E-20, 2)', 1.23456123456E-20, True, mm(fs('1.23 45 61 23 45 6*10^-20')));
  Test({LINENUM}2811, 'SetDigitGrouping(1.23456123456E-20, 3)', 1.23456123456E-20, True, mm(fs('1.234 561 234 56*10^-20')));
  Test({LINENUM}2812, 'SetDigitGrouping(1.23456123456E-20, 4)', 1.23456123456E-20, True, mm(fs('1.2345 6123 456*10^-20')));
  Test({LINENUM}2813, 'SetDigitGrouping(1.23456123456E-20, 5)', 1.23456123456E-20, True, mm(fs('1.23456 12345 6*10^-20')));
  Test({LINENUM}2814, 'SetDigitGrouping(1.23456123456E-20, 6)', 1.23456123456E-20, True, mm(fs('1.234561 23456*10^-20')));
  Test({LINENUM}2815, 'SetDigitGrouping(1.23456123456E-20, 7)', 1.23456123456E-20, True, mm(fs('1.2345612 3456*10^-20')));
  Test({LINENUM}2816, 'SetDigitGrouping(1.23456123456E-20, 8)', 1.23456123456E-20, True, mm(fs('1.23456123 456*10^-20')));
  Test({LINENUM}2817, 'SetDigitGrouping(1.23456123456E-20, 9)', 1.23456123456E-20, True, mm(fs('1.234561234 56*10^-20')));
  Test({LINENUM}2818, 'SetDigitGrouping(1.23456123456E-20, 10)', 1.23456123456E-20, True, mm(fs('1.2345612345 6*10^-20')));
  Test({LINENUM}2819, 'SetDigitGrouping(1.23456123456E-20, 11)', 1.23456123456E-20, True, mm(fs('1.23456123456*10^-20')));
  Test({LINENUM}2820, 'SetDigitGrouping(1.23456123456E-20, 12)', 1.23456123456E-20, True, mm(fs('1.23456123456*10^-20')));

  Test({LINENUM}2822, 'SetDigitGrouping(-1.23456123456E20, -1)', -1.23456123456E20, True, mm(fs('-1.23456123456*10^20')));
  Test({LINENUM}2823, 'SetDigitGrouping(-1.23456123456E20, 0)', -1.23456123456E20, True, mm(fs('-1.23456123456*10^20')));
  Test({LINENUM}2824, 'SetDigitGrouping(-1.23456123456E20, 1)', -1.23456123456E20, True, mm(fs('-1.2 3 4 5 6 1 2 3 4 5 6*10^20')));
  Test({LINENUM}2825, 'SetDigitGrouping(-1.23456123456E20, 2)', -1.23456123456E20, True, mm(fs('-1.23 45 61 23 45 6*10^20')));
  Test({LINENUM}2826, 'SetDigitGrouping(-1.23456123456E20, 3)', -1.23456123456E20, True, mm(fs('-1.234 561 234 56*10^20')));
  Test({LINENUM}2827, 'SetDigitGrouping(-1.23456123456E20, 4)', -1.23456123456E20, True, mm(fs('-1.2345 6123 456*10^20')));
  Test({LINENUM}2828, 'SetDigitGrouping(-1.23456123456E20, 5)', -1.23456123456E20, True, mm(fs('-1.23456 12345 6*10^20')));
  Test({LINENUM}2829, 'SetDigitGrouping(-1.23456123456E20, 6)', -1.23456123456E20, True, mm(fs('-1.234561 23456*10^20')));
  Test({LINENUM}2830, 'SetDigitGrouping(-1.23456123456E20, 7)', -1.23456123456E20, True, mm(fs('-1.2345612 3456*10^20')));
  Test({LINENUM}2831, 'SetDigitGrouping(-1.23456123456E20, 8)', -1.23456123456E20, True, mm(fs('-1.23456123 456*10^20')));
  Test({LINENUM}2832, 'SetDigitGrouping(-1.23456123456E20, 9)', -1.23456123456E20, True, mm(fs('-1.234561234 56*10^20')));
  Test({LINENUM}2833, 'SetDigitGrouping(-1.23456123456E20, 10)', -1.23456123456E20, True, mm(fs('-1.2345612345 6*10^20')));
  Test({LINENUM}2834, 'SetDigitGrouping(-1.23456123456E20, 11)', -1.23456123456E20, True, mm(fs('-1.23456123456*10^20')));
  Test({LINENUM}2835, 'SetDigitGrouping(-1.23456123456E20, 12)', -1.23456123456E20, True, mm(fs('-1.23456123456*10^20')));

  Test({LINENUM}2837, 'SetDigitGrouping(-1.23456123456E-20, -1)', -1.23456123456E-20, True, mm(fs('-1.23456123456*10^-20')));
  Test({LINENUM}2838, 'SetDigitGrouping(-1.23456123456E-20, 0)', -1.23456123456E-20, True, mm(fs('-1.23456123456*10^-20')));
  Test({LINENUM}2839, 'SetDigitGrouping(-1.23456123456E-20, 1)', -1.23456123456E-20, True, mm(fs('-1.2 3 4 5 6 1 2 3 4 5 6*10^-20')));
  Test({LINENUM}2840, 'SetDigitGrouping(-1.23456123456E-20, 2)', -1.23456123456E-20, True, mm(fs('-1.23 45 61 23 45 6*10^-20')));
  Test({LINENUM}2841, 'SetDigitGrouping(-1.23456123456E-20, 3)', -1.23456123456E-20, True, mm(fs('-1.234 561 234 56*10^-20')));
  Test({LINENUM}2842, 'SetDigitGrouping(-1.23456123456E-20, 4)', -1.23456123456E-20, True, mm(fs('-1.2345 6123 456*10^-20')));
  Test({LINENUM}2843, 'SetDigitGrouping(-1.23456123456E-20, 5)', -1.23456123456E-20, True, mm(fs('-1.23456 12345 6*10^-20')));
  Test({LINENUM}2844, 'SetDigitGrouping(-1.23456123456E-20, 6)', -1.23456123456E-20, True, mm(fs('-1.234561 23456*10^-20')));
  Test({LINENUM}2845, 'SetDigitGrouping(-1.23456123456E-20, 7)', -1.23456123456E-20, True, mm(fs('-1.2345612 3456*10^-20')));
  Test({LINENUM}2846, 'SetDigitGrouping(-1.23456123456E-20, 8)', -1.23456123456E-20, True, mm(fs('-1.23456123 456*10^-20')));
  Test({LINENUM}2847, 'SetDigitGrouping(-1.23456123456E-20, 9)', -1.23456123456E-20, True, mm(fs('-1.234561234 56*10^-20')));
  Test({LINENUM}2848, 'SetDigitGrouping(-1.23456123456E-20, 10)', -1.23456123456E-20, True, mm(fs('-1.2345612345 6*10^-20')));
  Test({LINENUM}2849, 'SetDigitGrouping(-1.23456123456E-20, 11)', -1.23456123456E-20, True, mm(fs('-1.23456123456*10^-20')));
  Test({LINENUM}2850, 'SetDigitGrouping(-1.23456123456E-20, 12)', -1.23456123456E-20, True, mm(fs('-1.23456123456*10^-20')));

  // Format: digit grouping (fixed)

  Test({LINENUM}2854, 'SetNumberFormat(1234.56789, "fixed") \ 6', 1234.56789, True, '1234.567890');
  Test({LINENUM}2855, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 6, -1)', 1234.56789, True, fs('1234.567890'));
  Test({LINENUM}2856, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 6, 0)', 1234.56789, True, fs('1234.567890'));
  Test({LINENUM}2857, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 6, 1)', 1234.56789, True, fs('1 2 3 4.5 6 7 8 9 0'));
  Test({LINENUM}2858, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 6, 2)', 1234.56789, True, fs('12 34.56 78 90'));
  Test({LINENUM}2859, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 6, 3)', 1234.56789, True, fs('1 234.567 890'));
  Test({LINENUM}2860, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 6, 4)', 1234.56789, True, fs('1234.5678 90'));
  Test({LINENUM}2861, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 6, 5)', 1234.56789, True, fs('1234.56789 0'));
  Test({LINENUM}2862, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 6, 6)', 1234.56789, True, fs('1234.567890'));
  Test({LINENUM}2863, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 6, 7)', 1234.56789, True, fs('1234.567890'));
  Test({LINENUM}2864, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 6, 8)', 1234.56789, True, fs('1234.567890'));

  Test({LINENUM}2866, 'SetNumberFormat(1234.56789, "fixed") \ 10', 1234.56789, True, '1234.5678900000');
  Test({LINENUM}2867, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 10, -1)', 1234.56789, True, fs('1234.5678900000'));
  Test({LINENUM}2868, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 10, 0)', 1234.56789, True, fs('1234.5678900000'));
  Test({LINENUM}2869, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 10, 1)', 1234.56789, True, fs('1 2 3 4.5 6 7 8 9 0 0 0 0 0'));
  Test({LINENUM}2870, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 10, 2)', 1234.56789, True, fs('12 34.56 78 90 00 00'));
  Test({LINENUM}2871, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 10, 3)', 1234.56789, True, fs('1 234.567 890 000 0'));
  Test({LINENUM}2872, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 10, 4)', 1234.56789, True, fs('1234.5678 9000 00'));
  Test({LINENUM}2873, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 10, 5)', 1234.56789, True, fs('1234.56789 00000'));
  Test({LINENUM}2874, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 10, 6)', 1234.56789, True, fs('1234.567890 0000'));
  Test({LINENUM}2875, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 10, 7)', 1234.56789, True, fs('1234.5678900 000'));
  Test({LINENUM}2876, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 10, 8)', 1234.56789, True, fs('1234.56789000 00'));
  Test({LINENUM}2877, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 10, 9)', 1234.56789, True, fs('1234.567890000 0'));
  Test({LINENUM}2878, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 10, 10)', 1234.56789, True, fs('1234.5678900000'));
  Test({LINENUM}2879, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 10, 11)', 1234.56789, True, fs('1234.5678900000'));
  Test({LINENUM}2880, 'SetDigitGrouping(SetNumberFormat(1234.56789, "fixed") \ 10, 12)', 1234.56789, True, fs('1234.5678900000'));

  Test({LINENUM}2882, 'SetNumberFormat(-1234.56789, "fixed") \ 6', -1234.56789, True, mm('-1234.567890'));
  Test({LINENUM}2883, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 6, -1)', -1234.56789, True, fs(mm('-1234.567890')));
  Test({LINENUM}2884, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 6, 0)', -1234.56789, True, fs(mm('-1234.567890')));
  Test({LINENUM}2885, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 6, 1)', -1234.56789, True, fs(mm('-1 2 3 4.5 6 7 8 9 0')));
  Test({LINENUM}2886, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 6, 2)', -1234.56789, True, fs(mm('-12 34.56 78 90')));
  Test({LINENUM}2887, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 6, 3)', -1234.56789, True, fs(mm('-1 234.567 890')));
  Test({LINENUM}2888, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 6, 4)', -1234.56789, True, fs(mm('-1234.5678 90')));
  Test({LINENUM}2889, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 6, 5)', -1234.56789, True, fs(mm('-1234.56789 0')));
  Test({LINENUM}2890, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 6, 6)', -1234.56789, True, fs(mm('-1234.567890')));
  Test({LINENUM}2891, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 6, 7)', -1234.56789, True, fs(mm('-1234.567890')));
  Test({LINENUM}2892, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 6, 8)', -1234.56789, True, fs(mm('-1234.567890')));

  Test({LINENUM}2894, 'SetNumberFormat(-1234.56789, "fixed") \ 10', -1234.56789, True, mm('-1234.5678900000'));
  Test({LINENUM}2895, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 10, -1)', -1234.56789, True, fs(mm('-1234.5678900000')));
  Test({LINENUM}2896, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 10, 0)', -1234.56789, True, fs(mm('-1234.5678900000')));
  Test({LINENUM}2897, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 10, 1)', -1234.56789, True, fs(mm('-1 2 3 4.5 6 7 8 9 0 0 0 0 0')));
  Test({LINENUM}2898, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 10, 2)', -1234.56789, True, fs(mm('-12 34.56 78 90 00 00')));
  Test({LINENUM}2899, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 10, 3)', -1234.56789, True, fs(mm('-1 234.567 890 000 0')));
  Test({LINENUM}2900, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 10, 4)', -1234.56789, True, fs(mm('-1234.5678 9000 00')));
  Test({LINENUM}2901, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 10, 5)', -1234.56789, True, fs(mm('-1234.56789 00000')));
  Test({LINENUM}2902, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 10, 6)', -1234.56789, True, fs(mm('-1234.567890 0000')));
  Test({LINENUM}2903, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 10, 7)', -1234.56789, True, fs(mm('-1234.5678900 000')));
  Test({LINENUM}2904, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 10, 8)', -1234.56789, True, fs(mm('-1234.56789000 00')));
  Test({LINENUM}2905, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 10, 9)', -1234.56789, True, fs(mm('-1234.567890000 0')));
  Test({LINENUM}2906, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 10, 10)', -1234.56789, True, fs(mm('-1234.5678900000')));
  Test({LINENUM}2907, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 10, 11)', -1234.56789, True, fs(mm('-1234.5678900000')));
  Test({LINENUM}2908, 'SetDigitGrouping(SetNumberFormat(-1234.56789, "fixed") \ 10, 12)', -1234.56789, True, fs(mm('-1234.5678900000')));


  //
  // Complex numbers
  //

  Test({LINENUM}2915, 'i', ImaginaryUnit, True, 'i');
  Test({LINENUM}2916, '−i', -ImaginaryUnit, True, '−i');
  Test({LINENUM}2917, '77⋅i', 77*ImaginaryUnit, True, '77⋅i');
  Test({LINENUM}2918, '−77⋅i', -77*ImaginaryUnit, True, '−77⋅i');
  Test({LINENUM}2919, '−1⋅i', -ImaginaryUnit, True, '−i');
  Test({LINENUM}2920, 'i^2', TASC(-1), True, mm('-1'));
  Test({LINENUM}2921, '1+i', 1 + ImaginaryUnit, True, mm('1 + i'));
  Test({LINENUM}2922, '7.5+i', 7.5 + ImaginaryUnit, True, mm('7.5 + i'));
  Test({LINENUM}2923, '7.5-i', 7.5 - ImaginaryUnit, True, mm('7.5 - i'));
  Test({LINENUM}2924, '2+3⋅i', 2 + 3*ImaginaryUnit, True, mm('2 + 3*i'));
  Test({LINENUM}2925, '-1+i', -1 + ImaginaryUnit, True, mm('-1 + i'));
  Test({LINENUM}2926, '-2+3⋅i', -2 + 3*ImaginaryUnit, True, mm('-2 + 3*i'));
  Test({LINENUM}2927, '1-i', 1 - ImaginaryUnit, True, mm('1 - i'));
  Test({LINENUM}2928, '2-3⋅i', 2 - 3*ImaginaryUnit, True, mm('2 - 3*i'));
  Test({LINENUM}2929, '-1-i', -1 - ImaginaryUnit, True, mm('-1 - i'));
  Test({LINENUM}2930, '-2-3⋅i', -2 - 3*ImaginaryUnit, True, mm('-2 - 3*i'));
  Test({LINENUM}2931, 'sqrt(-1)', ImaginaryUnit, True, 'i');
  Eps; Test({LINENUM}2932, 'i^i', TASC(exp(-pi/2)));
  Eps; Test({LINENUM}2933, 'arcsin(-2)', -1.57079632679489662 + 1.31695789692481671*ImaginaryUnit);
  Test({LINENUM}2934, '1/3 + i/3', 1/3 + ImaginaryUnit/3, True, '0.333333333333 + 0.333333333333⋅i');
  Test({LINENUM}2935, '(1/3 + i/3) \ 5', 1/3 + ImaginaryUnit/3, True, '0.33333 + 0.33333⋅i');
  Test({LINENUM}2936, '(1/3 + i/3) \ 2', 1/3 + ImaginaryUnit/3, True, '0.33 + 0.33⋅i');


  //
  // Booleans
  //

  Test({LINENUM}2943, 'true', true);
  Test({LINENUM}2944, 'false', false);
  Test({LINENUM}2945, 'true ∧ true ∧ true', true);
  Test({LINENUM}2946, 'false ∧ true ∧ true', false);
  Test({LINENUM}2947, 'true ∧ false ∧ true', false);
  Test({LINENUM}2948, 'true ∧ true ∧ false', false);
  Test({LINENUM}2949, 'false ∨ false ∨ false ∨ false', false);
  Test({LINENUM}2950, 'false ∨ false ∨ true ∨ false', true);
  Test({LINENUM}2951, '¬false', true);
  Test({LINENUM}2952, '¬true', false);
  Test({LINENUM}2953, '¬¬¬¬¬¬¬¬¬¬true', true);
  Test({LINENUM}2954, '¬¬¬¬¬¬¬¬¬¬¬true', false);


  //
  // Strings
  //

  Test({LINENUM}2961, '"Lorem ipsum"', 'Lorem ipsum', True, 'Lorem ipsum');
  Test({LINENUM}2962, '"cat"', 'cat', True, 'cat');
  Test({LINENUM}2963, '""', '', True, '');
  Test({LINENUM}2964, '"Lorem" + " " + "ipsum"', 'Lorem ipsum', True, 'Lorem ipsum');
  Test({LINENUM}2965, '"Lorem" ~ " " ~ "ipsum"', 'Lorem ipsum', True, 'Lorem ipsum');
  Test({LINENUM}2966, '"cat" + "" + ""', 'cat', True, 'cat');
  Test({LINENUM}2967, '"cat" ~ "" ~ ""', 'cat', True, 'cat');
  Test({LINENUM}2968, '"" + "cat"', 'cat', True, 'cat');
  Test({LINENUM}2969, '"" ~ "cat"', 'cat', True, 'cat');
  Test({LINENUM}2970, '"" + ""', '', True, '');
  Test({LINENUM}2971, '"" ~ ""', '', True, '');

  _s2 := DupeString('cat ', 250) + '…';           Assert(_s2.Length - 1 = 1000);

  _s := 'cat' + DupeString(' cat', 100);
  Test({LINENUM}2976, '"' + _s + '"', _s, True, _s);

  _s := 'cat' + DupeString(' cat', 1000);
  Test({LINENUM}2979, '"' + _s + '"', _s, True, _s2);

  _s := 'cat' + DupeString(' cat', 10000);
  Test({LINENUM}2982, '"' + _s + '"', _s, True, _s2);

  _s := 'cat' + DupeString(' cat', 100000);
  Test({LINENUM}2985, '"' + _s + '"', _s, True, _s2);

  _s := 'cat' + DupeString(' cat', 1000000);
  Test({LINENUM}2988, '"' + _s + '"', _s, True, _s2);

  _s := 'cat' + DupeString(' cat', 10000000);
  Test({LINENUM}2991, '"' + _s + '"', _s, True, _s2);

  _s := 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
  Test({LINENUM}2994, '"' + _s + '"', _s, True, _s);
  Test({LINENUM}2995, '"' + _s + '" \11', _s, True, 'Lorem ipsum…');
  Test({LINENUM}2996, '"' + _s + '" \5', _s, True, 'Lorem…');
  Test({LINENUM}2997, '"' + _s + '" \2', _s, True, 'Lo…');
  Test({LINENUM}2998, '"' + _s + '" \1', _s, True, 'L…');

  Test({LINENUM}3000, 'SetMaxLen("' + _s + '", 11)', _s, True, 'Lorem ipsum…');

  Test({LINENUM}3002, '"' + _s + '" \0', _s, True, _s);
  Test({LINENUM}3003, 'SetMaxLen("' + _s + '", 0)', _s, True, _s);

  Test({LINENUM}3005, '"' + _s + '" \ -1', failure, 'A non-negative integer was expected as argument 2, but "-1" was given.');
  Test({LINENUM}3006, 'SetMaxLen("' + _s + '", -1)', failure, 'A non-negative integer was expected as argument 2, but "-1" was given.');

  Test({LINENUM}3008, '"alfa" + ¶ + "beta"', 'alfa'#13#10'beta', True, 'alfa↲beta');
  TestSL({LINENUM}3009, '"alfa" + ¶ + "beta"', 'alfa↲beta');
  TestML({LINENUM}3010, '"alfa" + ¶ + "beta"', 'alfa'#13#10'beta');

  Test({LINENUM}3012, '"A new book named ""Cats""."', 'A new book named "Cats".', True, 'A new book named "Cats".');
  Test({LINENUM}3013, '"The empty string is """"."', 'The empty string is "".', True, 'The empty string is "".');
  Test({LINENUM}3014, '""""""', '""', True, '""');

  Test({LINENUM}3016, '"alfa beta', ESyntaxException, 'Unterminated string literal "alfa beta" starting at column 1.');
  Test({LINENUM}3017, '"alfa" + "beta', ESyntaxException, 'Unterminated string literal "beta" starting at column 10.');
  Test({LINENUM}3018, '"', ESyntaxException, 'Unterminated string literal "" starting at column 1.');
  Test({LINENUM}3019, '"""""', ESyntaxException, 'Unterminated string literal """""" starting at column 1.');

  Test({LINENUM}3021, '"Dogs are cute."[1]', 'D');
  Test({LINENUM}3022, '"Dogs are cute."[2]', 'o');
  Test({LINENUM}3023, '"Dogs are cute."[3]', 'g');
  Test({LINENUM}3024, '"Dogs are cute."[4]', 's');
  Test({LINENUM}3025, '"Dogs are cute."[5]', ' ');
  Test({LINENUM}3026, '"Dogs are cute."[6]', 'a');
  Test({LINENUM}3027, '"Dogs are cute."[7]', 'r');
  Test({LINENUM}3028, '"Dogs are cute."[8]', 'e');
  Test({LINENUM}3029, '"Dogs are cute."[9]', ' ');
  Test({LINENUM}3030, '"Dogs are cute."[10]', 'c');
  Test({LINENUM}3031, '"Dogs are cute."[11]', 'u');
  Test({LINENUM}3032, '"Dogs are cute."[12]', 't');
  Test({LINENUM}3033, '"Dogs are cute."[13]', 'e');
  Test({LINENUM}3034, '"Dogs are cute."[14]', '.');

  Test({LINENUM}3036, '"Dogs are cute."[15]', failure, 'Index 15 out of bounds.');

  Test({LINENUM}3038, '"Dogs are cute."[-1]', '.');
  Test({LINENUM}3039, '"Dogs are cute."[-2]', 'e');
  Test({LINENUM}3040, '"Dogs are cute."[-3]', 't');
  Test({LINENUM}3041, '"Dogs are cute."[-4]', 'u');
  Test({LINENUM}3042, '"Dogs are cute."[-5]', 'c');
  Test({LINENUM}3043, '"Dogs are cute."[-6]', ' ');
  Test({LINENUM}3044, '"Dogs are cute."[-7]', 'e');
  Test({LINENUM}3045, '"Dogs are cute."[-8]', 'r');
  Test({LINENUM}3046, '"Dogs are cute."[-9]', 'a');
  Test({LINENUM}3047, '"Dogs are cute."[-10]', ' ');
  Test({LINENUM}3048, '"Dogs are cute."[-11]', 's');
  Test({LINENUM}3049, '"Dogs are cute."[-12]', 'g');
  Test({LINENUM}3050, '"Dogs are cute."[-13]', 'o');
  Test({LINENUM}3051, '"Dogs are cute."[-14]', 'D');

  Test({LINENUM}3053, '"Dogs are cute."[-15]', failure, 'Index -15 out of bounds.');

  Test({LINENUM}3055, '"Dogs are cute."[0]', failure, 'Index 0 out of bounds.');

  Test({LINENUM}3057, '"Dogs are cute."[5] ≔ "G"', failure, 'Left side cannot be assigned to.');
  Test({LINENUM}3058, '"Dogs are cute."[-2] ≔ "G"', failure, 'Left side cannot be assigned to.');
  Test({LINENUM}3059, '"Dogs are cute."[25] ≔ "G"', failure, 'Left side cannot be assigned to.');
  Test({LINENUM}3060, '"Dogs are cute."[-25] ≔ "G"', failure, 'Left side cannot be assigned to.');
  Test({LINENUM}3061, '"Dogs are cute."[0] ≔ "G"', failure, 'Left side cannot be assigned to.');

  Test({LINENUM}3063, '("A" + "B")[1]', 'A');
  Test({LINENUM}3064, '("A" + "B")[2]', 'B');
  Test({LINENUM}3065, '("A" + "B")[3]', failure, 'Index 3 out of bounds.');

  Test({LINENUM}3067, '("A" + "B")[-1]', 'B');
  Test({LINENUM}3068, '("A" + "B")[-2]', 'A');
  Test({LINENUM}3069, '("A" + "B")[-3]', failure, 'Index -3 out of bounds.');

  Test({LINENUM}3071, '("A" + "B")[0]', failure, 'Index 0 out of bounds.');

  Test({LINENUM}3073, '""[-3]', failure, 'Index -3 out of bounds.');
  Test({LINENUM}3074, '""[-2]', failure, 'Index -2 out of bounds.');
  Test({LINENUM}3075, '""[-1]', failure, 'Index -1 out of bounds.');
  Test({LINENUM}3076, '""[0]', failure, 'Index 0 out of bounds.');
  Test({LINENUM}3077, '""[1]', failure, 'Index 1 out of bounds.');
  Test({LINENUM}3078, '""[2]', failure, 'Index 2 out of bounds.');
  Test({LINENUM}3079, '""[3]', failure, 'Index 3 out of bounds.');

  Test({LINENUM}3081, 'struct("a": 42, "b": "dog").b[1]', 'd');
  Test({LINENUM}3082, 'struct("a": 42, "b": "dog").b[2]', 'o');
  Test({LINENUM}3083, 'struct("a": 42, "b": "dog").b[3]', 'g');
  Test({LINENUM}3084, 'struct("a": 42, "b": "dog").b[4]', failure, 'Index 4 out of bounds.');

  Test({LINENUM}3086, 'struct("a": 42, "b": "dog").b[-1]', 'g');
  Test({LINENUM}3087, 'struct("a": 42, "b": "dog").b[-2]', 'o');
  Test({LINENUM}3088, 'struct("a": 42, "b": "dog").b[-3]', 'd');
  Test({LINENUM}3089, 'struct("a": 42, "b": "dog").b[-4]', failure, 'Index -4 out of bounds.');

  Test({LINENUM}3091, 'struct("a": 42, "b": "dog").b[0]', failure, 'Index 0 out of bounds.');

  Test({LINENUM}3093, 'struct("a": 42, "b": "dog").b[2] ≔ "a"', failure, 'Left side cannot be assigned to.');


  //
  // Real vectors
  //

  Test({LINENUM}3100, '❨1, 0, 0❩', [1, 0, 0]);                                                  // ❨❩
  Test({LINENUM}3101, '❨1, 2, 3❩', [1, 2, 3]);
  Test({LINENUM}3102, '❨1, -1❩', [1, -1]);
  Test({LINENUM}3103, '❨1❩', [1]);
  Test({LINENUM}3104, '❨0❩', [0]);
  Test({LINENUM}3105, '❨-1❩', [-1]);

  Test({LINENUM}3107, '❨2, −3, 1❩[1]', 2.0);
  Test({LINENUM}3108, '❨2, −3, 1❩[2]', -3.0);
  Test({LINENUM}3109, '❨2, −3, 1❩[3]', 1.0);
  Test({LINENUM}3110, '❨2, −3, 1❩[4]', failure, 'Index 4 out of bounds.');

  Test({LINENUM}3112, '❨2, −3, 1❩[-1]', 1.0);
  Test({LINENUM}3113, '❨2, −3, 1❩[-2]', -3.0);
  Test({LINENUM}3114, '❨2, −3, 1❩[-3]', 2.0);
  Test({LINENUM}3115, '❨2, −3, 1❩[-4]', failure, 'Index -4 out of bounds.');

  Test({LINENUM}3117, '❨2, −3, 1❩[0]', failure, 'Index 0 out of bounds.');

  Test({LINENUM}3119, '❨2, −3, 1❩[2] ≔ 3', failure, 'Left side cannot be assigned to.');
  Test({LINENUM}3120, '❨2, −3, 1❩[20] ≔ 3', failure, 'Left side cannot be assigned to.');

  Test({LINENUM}3122, 'vector(1, 2, 3)', [1, 2, 3]);

  Test({LINENUM}3124, '❨1, 2, 3❩ + ❨10, 100, 1000❩', [11, 102, 1003]);

  TestSL({LINENUM}3126, '❨1, 2, 3❩', '(1, 2, 3)');
  TestML({LINENUM}3127, '❨1, 2, 3❩', ' ⎛1⎞'#13#10'e⎜2⎟'#13#10' ⎝3⎠');

  TestML({LINENUM}3129, '❨1❩', '(1)');
  TestML({LINENUM}3130, '❨1, 2❩', ' ⎛1⎞'#13#10'e⎝2⎠');
  TestML({LINENUM}3131, '❨1, 2, 3❩', ' ⎛1⎞'#13#10'e⎜2⎟'#13#10' ⎝3⎠');

  Test({LINENUM}3133, 'SequenceVector(100)', [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]);
  TestSL({LINENUM}3134, 'SequenceVector(100)', '(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,'+' 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,'+' 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100)');
  TestML({LINENUM}3135, 'SequenceVector(100)', '(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,'+' 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,'+' 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100)'); // (way) beyond default vertical until

  Test({LINENUM}3137, 'SequenceVector(200)', [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200]);
  TestSL({LINENUM}3138, 'SequenceVector(200)', '(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, '+'33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, '+'67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, …)');
  TestML({LINENUM}3139, 'SequenceVector(200)', '(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, '+'33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, '+'67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, …)'); // (way) beyond default vertical until

  Test({LINENUM}3141, '❨1, 2, 3, 4, 5, 6, 7, 8, 9, 10❩', [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
  TestSL({LINENUM}3142, '❨1, 2, 3, 4, 5, 6, 7, 8, 9, 10❩', '(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)');

  Test({LINENUM}3144, '❨1, 2, 3, 4, 5, 6, 7, 8, 9, 10❩ \ 10', [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
  TestSL({LINENUM}3145, '❨1, 2, 3, 4, 5, 6, 7, 8, 9, 10❩ \ 10', '(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)');

  Test({LINENUM}3147, '❨1, 2, 3, 4, 5, 6, 7, 8, 9, 10❩ \ 9', [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
  TestSL({LINENUM}3148, '❨1, 2, 3, 4, 5, 6, 7, 8, 9, 10❩ \ 9', '(1, 2, 3, 4, 5, 6, 7, 8, 9, …)');

  Test({LINENUM}3150, '❨1, 2, 3, 4, 5, 6, 7, 8, 9, 10❩ \ 5', [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
  TestSL({LINENUM}3151, '❨1, 2, 3, 4, 5, 6, 7, 8, 9, 10❩ \ 5', '(1, 2, 3, 4, 5, …)');

  Test({LINENUM}3153, '❨1, 2, 3, 4, 5, 6, 7, 8, 9, 10❩ \ 2', [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
  TestSL({LINENUM}3154, '❨1, 2, 3, 4, 5, 6, 7, 8, 9, 10❩ \ 2', '(1, 2, …)');

  Test({LINENUM}3156, '❨1, 2, 3, 4, 5, 6, 7, 8, 9, 10❩ \ 1', [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
  TestSL({LINENUM}3157, '❨1, 2, 3, 4, 5, 6, 7, 8, 9, 10❩ \ 1', '(1, …)');

  Test({LINENUM}3159, '❨1, 2, 3, 4, 5, 6❩', [1, 2, 3, 4, 5, 6]);
  TestSL({LINENUM}3160, '❨1, 2, 3, 4, 5, 6❩', '(1, 2, 3, 4, 5, 6)');
  TestML({LINENUM}3161, '❨1, 2, 3, 4, 5, 6❩', ' ⎛1⎞'#13#10' ⎜2⎟'#13#10' ⎜3⎟'#13#10'e⎜4⎟'#13#10' ⎜5⎟'#13#10' ⎝6⎠');

  Test({LINENUM}3163, '❨1, 2, 3, 4, 5, 6❩ \ 3', [1, 2, 3, 4, 5, 6]);
  TestSL({LINENUM}3164, '❨1, 2, 3, 4, 5, 6❩ \ 3', '(1, 2, 3, …)');
  TestML({LINENUM}3165, '❨1, 2, 3, 4, 5, 6❩ \ 3', ' ⎛1⎞'#13#10' ⎜2⎟'#13#10'e⎜3⎟'#13#10' ⎝⋮⎠');

  Test({LINENUM}3167, '❨❩', ESyntaxException, 'Empty bracket at column 1.'); // would make sense to allow syntactically, to get vector's error message instead
  Test({LINENUM}3168, 'vector()', failure, 'A vector must have dimension at least one.');

  Test({LINENUM}3170, '❨1, 1/2, 1/3❩', [1, 1/2, 1/3]);
  TestML({LINENUM}3171, '❨1, 1/2, 1/3❩', ' ⎛      1       ⎞'#13#10'e⎜     0.5      ⎟'#13#10' ⎝0.333333333333⎠');
  TestML({LINENUM}3172, 'SetNumDigits(❨1, 1/2, 1/3❩, 4)', ' ⎛  1   ⎞'#13#10'e⎜ 0.5  ⎟'#13#10' ⎝0.3333⎠');
  TestML({LINENUM}3173, 'SetNumDigits(❨1/2, 1/3, 1/4❩, 4) \ 2', ' ⎛ 0.5  ⎞'#13#10'e⎜0.3333⎟'#13#10' ⎝  ⋮   ⎠');

  TestSL({LINENUM}3175, '❨1, 1/2, 1/3❩', '(1, 0.5, 0.333333333333)');
  TestSL({LINENUM}3176, 'SetNumDigits(❨1, 1/2, 1/3❩, 4)', '(1, 0.5, 0.3333)');
  TestSL({LINENUM}3177, 'SetNumDigits(❨1/2, 1/3, 1/4❩, 4) \ 2', '(0.5, 0.3333, …)');

  TestML({LINENUM}3179, 'SetDigitGrouping(❨12432435, 65426277, 763763588, 62565245246, 415❩, 3)', ' ⎛  12 432 435  ⎞'#13#10' ⎜  65 426 277  ⎟'#13#10'e⎜ 763 763 588  ⎟'#13#10' ⎜62 565 245 246⎟'#13#10' ⎝     415      ⎠');
  TestSL({LINENUM}3180, 'SetDigitGrouping(❨12432435, 65426277, 763763588, 62565245246, 415❩, 3)', '(12 432 435, 65 426 277, 763 763 588, 62 565 245 246, 415)');


  //
  // Complex vectors
  //

  Test({LINENUM}3187, '❨i, 0, 0❩', [ImaginaryUnit, 0, 0]);                                      // ❨❩
  Test({LINENUM}3188, '❨i, 2, 3❩', [ImaginaryUnit, 2, 3]);
  Test({LINENUM}3189, '❨i, -1❩', [ImaginaryUnit, -1]);
  Test({LINENUM}3190, '❨i❩', [ImaginaryUnit]);
  Test({LINENUM}3191, '❨-i❩', [-ImaginaryUnit]);

  TestML({LINENUM}3193, '❨i❩', '(i)');
  TestML({LINENUM}3194, '❨i, 2❩', ' ⎛i⎞'#13#10'e⎝2⎠');
  TestML({LINENUM}3195, '❨i, 2, 3❩', ' ⎛i⎞'#13#10'e⎜2⎟'#13#10' ⎝3⎠');

  Test({LINENUM}3197, '❨2, −3, i❩[1]', TASC(2.0));
  Test({LINENUM}3198, '❨2, −3, i❩[2]', TASC(-3.0));
  Test({LINENUM}3199, '❨2, −3, i❩[3]', ImaginaryUnit);
  Test({LINENUM}3200, '❨2, −3, i❩[4]', failure, 'Index 4 out of bounds.');

  Test({LINENUM}3202, '❨2, −3, i❩[-1]', ImaginaryUnit);
  Test({LINENUM}3203, '❨2, −3, i❩[-2]', TASC(-3.0));
  Test({LINENUM}3204, '❨2, −3, i❩[-3]', TASC(2.0));
  Test({LINENUM}3205, '❨2, −3, i❩[-4]', failure, 'Index -4 out of bounds.');

  Test({LINENUM}3207, '❨2, −3, i❩[0]', failure, 'Index 0 out of bounds.');

  Test({LINENUM}3209, '❨2, −3, i❩[2] ≔ 3', failure, 'Left side cannot be assigned to.');
  Test({LINENUM}3210, '❨2, −3, i❩[20] ≔ 3', failure, 'Left side cannot be assigned to.');

  Test({LINENUM}3212, 'vector(i, 2, 3)', [ImaginaryUnit, 2, 3]);

  Test({LINENUM}3214, '❨i, 2, 3❩ + ❨10, 100, 1000❩', [ImaginaryUnit + 10, 102, 1003]);

  TestSL({LINENUM}3216, '❨i, 2, 3❩', '(i, 2, 3)');
  TestML({LINENUM}3217, '❨i, 2, 3❩', ' ⎛i⎞'#13#10'e⎜2⎟'#13#10' ⎝3⎠');

  Test({LINENUM}3219, '❨i, 2, 3, 4, 5, 6, 7, 8, 9, 10❩', [ImaginaryUnit, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
  TestSL({LINENUM}3220, '❨i, 2, 3, 4, 5, 6, 7, 8, 9, 10❩', '(i, 2, 3, 4, 5, 6, 7, 8, 9, 10)');

  Test({LINENUM}3222, '❨i, 2, 3, 4, 5, 6, 7, 8, 9, 10❩ \ 10', [ImaginaryUnit, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
  TestSL({LINENUM}3223, '❨i, 2, 3, 4, 5, 6, 7, 8, 9, 10❩ \ 10', '(i, 2, 3, 4, 5, 6, 7, 8, 9, 10)');

  Test({LINENUM}3225, '❨i, 2, 3, 4, 5, 6, 7, 8, 9, 10❩ \ 9', [ImaginaryUnit, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
  TestSL({LINENUM}3226, '❨i, 2, 3, 4, 5, 6, 7, 8, 9, 10❩ \ 9', '(i, 2, 3, 4, 5, 6, 7, 8, 9, …)');

  Test({LINENUM}3228, '❨i, 2, 3, 4, 5, 6, 7, 8, 9, 10❩ \ 5', [ImaginaryUnit, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
  TestSL({LINENUM}3229, '❨i, 2, 3, 4, 5, 6, 7, 8, 9, 10❩ \ 5', '(i, 2, 3, 4, 5, …)');

  Test({LINENUM}3231, '❨i, 2, 3, 4, 5, 6, 7, 8, 9, 10❩ \ 2', [ImaginaryUnit, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
  TestSL({LINENUM}3232, '❨i, 2, 3, 4, 5, 6, 7, 8, 9, 10❩ \ 2', '(i, 2, …)');

  Test({LINENUM}3234, '❨i, 2, 3, 4, 5, 6, 7, 8, 9, 10❩ \ 1', [ImaginaryUnit, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
  TestSL({LINENUM}3235, '❨i, 2, 3, 4, 5, 6, 7, 8, 9, 10❩ \ 1', '(i, …)');

  Test({LINENUM}3237, '❨i, 2, 3, 4, 5, 6❩', [ImaginaryUnit, 2, 3, 4, 5, 6]);
  TestSL({LINENUM}3238, '❨i, 2, 3, 4, 5, 6❩', '(i, 2, 3, 4, 5, 6)');
  TestML({LINENUM}3239, '❨i, 2, 3, 4, 5, 6❩', ' ⎛i⎞'#13#10' ⎜2⎟'#13#10' ⎜3⎟'#13#10'e⎜4⎟'#13#10' ⎜5⎟'#13#10' ⎝6⎠');

  Test({LINENUM}3241, '❨i, 2, 3, 4, 5, 6❩ \ 3', [ImaginaryUnit, 2, 3, 4, 5, 6]);
  TestSL({LINENUM}3242, '❨i, 2, 3, 4, 5, 6❩ \ 3', '(i, 2, 3, …)');
  TestML({LINENUM}3243, '❨i, 2, 3, 4, 5, 6❩ \ 3', ' ⎛i⎞'#13#10' ⎜2⎟'#13#10'e⎜3⎟'#13#10' ⎝⋮⎠');

  Test({LINENUM}3245, '❨i, 1/2, 1/3❩', [ImaginaryUnit, 1/2, 1/3]);
  TestML({LINENUM}3246, '❨i, 1/2, 1/3❩', ' ⎛      i       ⎞'#13#10'e⎜     0.5      ⎟'#13#10' ⎝0.333333333333⎠');
  TestML({LINENUM}3247, 'SetNumDigits(❨i, 1/2, 1/3❩, 4)', ' ⎛  i   ⎞'#13#10'e⎜ 0.5  ⎟'#13#10' ⎝0.3333⎠');
  TestML({LINENUM}3248, 'SetNumDigits(❨i/2, 1/3, 1/4❩, 4) \ 2', ' ⎛0.5⋅i ⎞'#13#10'e⎜0.3333⎟'#13#10' ⎝  ⋮   ⎠');

  TestSL({LINENUM}3250, '❨i, 1/2, 1/3❩', '(i, 0.5, 0.333333333333)');
  TestSL({LINENUM}3251, 'SetNumDigits(❨i, 1/2, 1/3❩, 4)', '(i, 0.5, 0.3333)');
  TestSL({LINENUM}3252, 'SetNumDigits(❨i/2, 1/3, 1/4❩, 4) \ 2', '(0.5⋅i, 0.3333, …)');

  TestML({LINENUM}3254, 'SetDigitGrouping(❨12432435, 65426277, 763763588, 62565245246⋅i, 415❩, 3)', ' ⎛   12 432 435   ⎞'#13#10' ⎜   65 426 277   ⎟'#13#10'e⎜  763 763 588   ⎟'#13#10' ⎜62 565 245 246⋅i⎟'#13#10' ⎝      415       ⎠');
  TestSL({LINENUM}3255, 'SetDigitGrouping(❨12432435, 65426277, 763763588, 62565245246⋅i, 415❩, 3)', '(12 432 435, 65 426 277, 763 763 588, 62 565 245 246⋅i, 415)');


  //
  // Real matrices