Options

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

  • Options
    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
  • Options
    DuikmeesterDuikmeester Member Posts: 304
    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.
  • Options
    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
  • Options
    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
  • Options
    DuikmeesterDuikmeester Member Posts: 304
    edited 2018-02-20
    @Slawek_Guzek you forgot a line:
    EVALUATE(aInteger,aResult);
    
  • Options
    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.