Post Reply 
Repeating Decimals / Recurring Decimals
01-26-2018, 11:02 PM (This post was last modified: 01-27-2018 07:27 PM by StephenG1CMZ.)
Post: #4
RE: Repeating Decimals / Recurring Decimals
Version 0.4 has cosmetic improvements and help. It adds a CAS variable which show more digits, but I have yet to find out how use that in PPL - Whenever I try to turn it into a string, it turns into a real instead.
(Update: I have found the required syntax to do that now, so expect another release soon.)

Code:


 LOCAL CRID:="REPEATING DECIMAL V 0.4 \n©2018 StephenG1CMZ";
 LOCAL ALGM:="Following Joe Horn's algorithm: http://www.hpmuseum.org/forum/thread-9919.html";

 //Written 2018 StephenG1CMZ
 //Following Joe Horn`s algorithm using Multiplicative Order

 //This implement yields useful results but
 //Large Repeating Lengths (>12repeatingdigits) yield weird output eg NN=301

 //NB Sometimes the leading 0. is included in the output
 //but sometimes it is not...EG NN=14 Why?

 LOCAL ImpRELEN:=12;//(EMPIRICAL)
 LOCAL ImpTransientLEN:=12;//(EMPIRICAL)
 //Should NDIGITS>12 fail?: not tested.

 LOCAL FR2,FR5;//GLOBAL RETURN
 EXPORT TransientLEN;//Length of Transient
 EXPORT RepetendLEN;//Length of Recurring Digits/Repeating Digits
  //^Len == Decimal Digits Only
 EXPORT USCORE:="_";//CHANGE TO EMPTY STRING IF YOU WISH TO EVAL THE STRING
 EXPORT DECSEP:=".";//DECIMAL SEPARATOR (USED WHEN TRANSIENTLEN=0,IDEALLY GET FROM SYSTEM)
 EXPORT TESTED:=0;
 LOCAL STNAN:="(NaN)";

 MultiplicativeOrder10();//FORWARD

 EXPORT ABOUT()
 BEGIN
  PRINT();
  PRINT(CRID);
  PRINT(ALGM);
 END;

 EXPORT HELP()
 BEGIN
  PRINT();
  PRINT("Recurring/Repeating: Given integer NN, return a string of its real reciprocal with _ marking any recurring digits.");
  PRINT("ShowMe: Shows a range of values.");
  PRINT(" ");
  PRINT("Variables In: Strings DECSEP,USCORE ");
  PRINT("Variables Out: RepetendLEN, TransientLEN");
  PRINT("CAS: temporary variable shows more digits: Can this be used from PPL?");
  PRINT("{Repetend,Transient}>12 digits: NaN implemented (PPL Limit).");
 END;

 ZEROS(NN)
 BEGIN
  IF NN>0 THEN
   RETURN "0"+ZEROS(NN-1);
  END;
  RETURN ""; 
 END;
 
 MaxFactor25(NN)
 BEGIN 
  LOCAL MAXFACTR:=0;
  LOCAL LST,LSTB,LP,II;
  
  LST:=mat2list(ifactors(NN)); //BASES AND COUNTSETC
  //EXTRACT BASES (2,5) ETC
  LSTB:=IFTE(SIZE(LST),MAKELIST(LST(2*II-1),II,1,(SIZE(LST)/2)),{});//{} HANDLES NN=1 
 
  FR2:=0; FR5:=0;
  LP:=POS(LSTB,2); 
  IF LP THEN
   FR2:=LST(2*LP);//EXPONENT
  END;
  LP:=POS(LSTB,5); 
  IF LP THEN
   FR5:=LST(2*LP);//EXPONENT
  END;
  
  MAXFACTR:=MAX(FR2,FR5);
  RETURN MAXFACTR;//0=NONE
 END;

 
 EXPORT GetTransient(NN)
 //NOTE: THIS IS CALLED BY Recurring/Repeating.
 BEGIN
  LOCAL TRANSIENTPART;

  TransientLEN:=MaxFactor25(NN);
  IF TransientLEN THEN
   IF TransientLEN>12 THEN
    //EG NN=8192
    //MSGBOX("Caution:TransientLEN= "+TransientLEN);//FIX TBC
    TRANSIENTPART:="(NaN)";//IP(1/NN);//AVOID TRUNCATE
   ELSE
    TRANSIENTPART:=TRUNCATE((1/NN),TransientLEN);//TRUNCATE BREAKS AT 13
   END;
  ELSE
   IF NN==0 THEN
    RETURN STNAN+"DIVBY0";
   END;
   TRANSIENTPART:=IP(1/NN)+DECSEP;
  END;
  RETURN TRANSIENTPART;
 END;
 
 ReDIGITS (NN )
 //NN INTEGER 
 BEGIN
  LOCAL STR:="";
  LOCAL TRANSIENTPART;
  LOCAL WHATSLEFT;
  LOCAL RP,NDIGITS;
  LOCAL ST:="";//STRINGVERSION
  LOCAL RESULTS:={};
  LOCAL RL;
  IF NN THEN
   RL:=1/NN;//DIAGNOSTIC ONLY:USUAL REAL
  ELSE
   RETURN STNAN+"DIVBY0";
  END;
  TRANSIENTPART:=GetTransient(NN); 
  WHATSLEFT:=exact(NN/(2^FR2*5^FR5));

  IF WHATSLEFT==1 THEN
   //RETURN TRANSIENTPART;//AVOID STALL
  END;
  //RepetendLEN:=MultiplicativeOrder(WHATSLEFT,10);
  RepetendLEN:=MultiplicativeOrder10(WHATSLEFT);

  NDIGITS:=TransientLEN+RepetendLEN;
  IF RepetendLEN THEN
   IF RepetendLEN>ImpRELEN THEN
    //TBD: A better test might be to search for ᴇ in the string
    ST:=STNAN;//Implementation limit:BAD IQUO?
   END;//FOR NOW SHOW THE WEIRD OUTPUT
   //MSGBOX({NDIGITS,NN});
   RP:=iquo((1*10^NDIGITS),NN);
  //MSGBOX(RP);
   CAS("temporary:=iquo((1*10^NDIGITS),NN)");
   //CAS("PRINT(temporary)");
   //PRINT(STR);
   //The string version asks for leading zeros I hoped
   //but no...pad it manually 
   //ST:=format(RP,"s"+NDIGITS); 
   ST:=ST+MID(ZEROS(NDIGITS-DIM(STRING(temporary)))+temporary,TransientLEN+1);
  END;
  RESULTS:=TRANSIENTPART+USCORE+ST;
 
  IF 0 THEN //DEBUG INFO
   PRINT(); 
   PRINT("Input Fraction: 1/"+NN+" = "+RL);
   PRINT("Whats Left: "+WHATSLEFT);
   PRINT("Multiplicative Order: "+RepetendLEN);
   //PRINT("Length: "+{TransientLEN,RepetendLEN});
   IF RepetendLEN>12 THEN //EXPECT REPEATING PART TO GO WEIRD
    PRINT("RepetendLEN>12: CAUTION");
   END;
   PRINT("TRANSIENT PART: "+IFTE(TRANSIENTLEN,TRANSIENTPART,TRANSIENTPART+" (none)"));
   PRINT(ST);
   PRINT(RESULTS);
  END;
  //RETURN RESULTS
  //Return a formatted string
  //(Relevant Lengths are returned globally) 
  RETURN RESULTS;
 END;
 
 EXPORT Recurring(NN)
 BEGIN
  RETURN ReDIGITS(NN); 
 END;
 //Some call them Recurring
 //Some call them Repeating
 EXPORT Repeating(NN)
 BEGIN
  RETURN ReDIGITS(NN);
 END;

 EXPORT Show1(NN)
 BEGIN
    LOCAL TRANSIENTPART;
    RECT_P();
    TEXTOUT_P(CRID,0,0,3);
    //TEXTOUT_P(ALGM,0,15,1);
    TEXTOUT_P("Fraction,Reduced Fraction,Real,Decimal:",0,40);
    TEXTOUT_P("1/"+NN,0,60);
    TEXTOUT_P(CAS(1/NN)+" Reduced Fraction",0,80);
    TEXTOUT_P(IFTE(NN,(1/NN)+" Real",(STNAN+"DIVBY0")),0,100);
    //DEBUG;
    TRANSIENTPART:=GetTransient(NN);
    TEXTOUT_P(TRANSIENTPART+" Transient Part",0,140);
    TEXTOUT_P(Recurring(NN)+" Decimal",0,120);
    TEXTOUT_P("Has "+TransientLEN+" Transient digits & "+RepetendLEN+" Repetend digits",0,180);
    TEXTOUT_P("Variable CAS.temporary may show more",0,200);
    //TEXTOUT_P(CAS("temporary"),0,180);//doesnt work:PPL
    TEXTOUT_P("Esc to continue",0,220);
    IF RepetendLEN>ImpRELEN OR TransientLEN>ImpTransientLEN THEN
     //Highlight Implement NaN
     TEXTOUT_P("Imp"+STNAN,320/2,220,3,RGB(255,0,0));
    END;
    WAIT; 
 END;


 EXPORT ShowMe(FIRST,LAST)
 BEGIN
  LOCAL NN;
  FOR NN FROM FIRST TO LAST DO
    Show1(NN);
  END;
 END;

 EXPORT MultiplicativeOrder10(WhatsLeft)
 //See http://www.hpmuseum.org/forum/thread-3212.html
 // WHATSLEFT
 BEGIN
  LOCAL AP:=0;
  LOCAL NOTFND:=1;
  LOCAL LST:={};//POSSIBLES TO CHECK

  IF WhatsLeft≠1 THEN
   //Get possibles
   LST:=mat2list(idivis(euler(WhatsLeft)));
   //Search possiblesfor a match
   WHILE AP<SIZE(LST) AND NOTFND DO
    AP:=AP+1;
    IF powmod(10,LST(AP),WhatsLeft)==1 THEN
     NOTFND:=0;//FOUND
    END;//IF
   END;//LOOP
  END;//IF
  //Return match
  //Return 0 if WL=1 or no match
  RETURN IFTE(NOTFND,0,LST(AP));
 END;

 TESTS()
 BEGIN
  LOCAL III,RR;
  FOR III FROM 1 TO 1000  DO
   //RECT_P();
   //TEXTOUT_P(III,0,120);
    //WAIT(2);
   TESTED:=III;
   RR:=ReDIGITS(III);  
  END;
 END;

 EXPORT REDECIMALS()
 BEGIN
  ABOUT(); 
  PRINT(TEVAL(TESTS));
 END;
The implementation returns NaN if either the Transient part or Repetend exceed 12 digits.

Stephen Lewkowicz (G1CMZ)
https://my.numworks.com/python/steveg1cmz
Visit this user's website Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
RE: Repeating Decimals - StephenG1CMZ - 01-21-2018, 11:01 AM
RE: Repeating Decimals / Recurring Decimals - StephenG1CMZ - 01-26-2018 11:02 PM



User(s) browsing this thread: 1 Guest(s)