Modulo on a big number

lightninglightning Member Posts: 15
Hi,

I need to perform a modulo operation on a very big number (30 digits, could even be all 9's), is it even possible to do that in Navision?
If so, how would i do that? It would be a simple VARIABLE MOD 97 operation.

Also, the 'number' is stored in a Text variable, since obviously integer can't hold a number of this magnitude

Answers

  • Slawek_GuzekSlawek_Guzek Member Posts: 1,690
    Nope. Such a large number cannot be represented on a regular PC.

    'Standard' arithmetic is limited to 64bits which is about 16 digits in case of double precision decimal, or 19 digits for big integer.

    Maybe some specialistic math software can handle it, NAV is not an exampe of one...
    Slawek Guzek
    Dynamics NAV, MS SQL Server, Wherescape RED;
    PRINCE2 Practitioner - License GR657010572SG
    GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
  • DuikmeesterDuikmeester Member Posts: 308
    edited 2018-02-16
    OBJECT Codeunit 50000 BigInteger
    {
      OBJECT-PROPERTIES
      {
        Date=;
        Time=;
        Version List=;
      }
      PROPERTIES
      {
        OnRun=VAR
                BigInteger@50000 : DotNet "'System.Numerics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Numerics.BigInteger";
                aResult@50001 : Text;
                aInteger@50002 : Integer;
              BEGIN
                aResult := BigInteger.Remainder(BigInteger.Parse('999999999999999999999999999999'),BigInteger.Parse('97')).ToString();
                EVALUATE(aInteger,aResult);
                MESSAGE('%1',aInteger); //84
              END;
    
      }
      CODE
      {
    
        BEGIN
        END.
      }
    }
    

    Edit: Oh, classic forum... Then it works only when using the 2009 RTC.
  • lightninglightning Member Posts: 15
    edited 2018-02-16
    Found a way, here's the code:

    WHILE STRLEN(CheckSumCalculator) > 6 DO
      CheckSumCalculator := CalculateModulus(COPYSTR(CheckSumCalculator,1,6), 97) + COPYSTR(CheckSumCalculator, 7)
    EVALUATE(ToInt, CheckSumCalculator);
    ToInt := ToInt MOD 97;
    


    And the CalculateModulus procedure
    EVALUATE(I,Number);
    I := I MOD Modulus;
    IF I = 0 THEN
      EXIT('');
    EXIT(FORMAT(I));
    

    I took the solution from "CheckIBAN" from NAV2017
  • Slawek_GuzekSlawek_Guzek Member Posts: 1,690
    edited 2018-02-16
    @Duikmeester
    Even in 3Tier - are you sure the results are correct?
    aResult := BigInteger.Remainder(
      BigInteger.Parse('979999990000000000000000000000'), BigInteger.Parse('97')).ToString();
    
    aResult2 := BigInteger.Remainder(
      BigInteger.Parse('979999990000000000000000000001'), BigInteger.Parse('97')).ToString();
    EVALUATE(aInteger2,aResult2);
    
    MESSAGE('%1, %2',aInteger, aInteger2); //0, 69
    
    Slawek Guzek
    Dynamics NAV, MS SQL Server, Wherescape RED;
    PRINCE2 Practitioner - License GR657010572SG
    GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
  • DuikmeesterDuikmeester Member Posts: 308
    edited 2018-02-20
    @Slawek_Guzek you forgot a line:
    EVALUATE(aInteger,aResult);
    
  • Slawek_GuzekSlawek_Guzek Member Posts: 1,690
    :blush:
    Slawek Guzek
    Dynamics NAV, MS SQL Server, Wherescape RED;
    PRINCE2 Practitioner - License GR657010572SG
    GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
Sign In or Register to comment.