HP Forums
Bug or Not? Taking STRING of a string whilst making leading zeros - Printable Version

+- HP Forums (https://www.hpmuseum.org/forum)
+-- Forum: HP Calculators (and very old HP Computers) (/forum-3.html)
+--- Forum: HP Prime (/forum-5.html)
+--- Thread: Bug or Not? Taking STRING of a string whilst making leading zeros (/thread-10053.html)



Bug or Not? Taking STRING of a string whilst making leading zeros - StephenG1CMZ - 01-29-2018 04:41 PM

I was trying to add some leading zeros into a string.
I discovered that if there is an unneccessary call to STRING the leading 0 doesnt appear.
Why aren't "9" and STRING("9") both of length 1, yielding 1 leading zero in the example code?
Code:

  
 
 ZEROS(NN)
 //LEADING ZEROS
 BEGIN
  //MSGBOX(NN);
  IF NN>0 THEN
   RETURN "0"+ZEROS(NN-1);
  END;
  RETURN ""; 
 END;
 
  
 EXPORT ReDIGITS (ALT )
 BEGIN
  //LOCAL NDIGITS:=2;
  LOCAL STR:="";
  LOCAL ST:="";//STRINGVERSION
   //CAS("temporary:=iquo((1*10^NDIGITS),2)");
   //ST:=CAS("string(temporary)");
   ST:="9";
   //The string version asks for leading zeros I hoped
   //but no...pad it manually 
   //STR:=CAS(format(ST,"s"+NDIGITS));
   IF ALT THEN //EXPECTED
    STR:=ZEROS(2-DIM((ST)));
   ELSE    //UNEXPECTED
    STR:=ZEROS(2-DIM(STRING(ST)));
   END;
   ST:=MID(STR+ST,TransientLEN+1);
   MSGBOX(STR);
   MSGBOX(ST);
  END; 

 EXPORT STBUG()
 BEGIN

 END;
Try with Alt 1 and Alt 0 to see the expected and erroneous output.

Is there a better way to get leading zeros in a string?


RE: Bug: Taking STRING of a string whilst making leading zeros - Carlos295pz - 01-29-2018 05:21 PM

Ans → 9
STRING(Ans) → "9"
STRING(Ans) → ""9""
STRING(Ans) → """"9""""
STRING(Ans) → """"""""9""""""""


RE: Bug or Not? Taking STRING of a string whilst making leading zeros - Didier Lachieze - 01-30-2018 11:38 AM

(01-29-2018 04:41 PM)StephenG1CMZ Wrote:  Why aren't "9" and STRING("9") both of length 1, yielding 1 leading zero in the example code?
"9" is a string of length 1, but STRING("9") is a string of length 3: '9' plus 2 double quote characters.

(01-29-2018 04:41 PM)StephenG1CMZ Wrote:  Is there a better way to get leading zeros in a string?
A simple way to get a string with N zeros: tail(STRING(10^N)), or if you prefer not to use a CAS function: MID(STRING(10^N),2,N).
It works for N>=0, returning "" for N=0.


RE: Bug or Not? Taking STRING of a string whilst making leading zeros - toml_12953 - 01-30-2018 12:53 PM

(01-29-2018 04:41 PM)StephenG1CMZ Wrote:  Is there a better way to get leading zeros in a string?

If the number is N and length you want is X, I use:

Code:
RIGHT(MID(STRING(10^X,1),2)+N,X)


Thanks to Joe's post, I changed the STRING function to include the format type.


RE: Bug or Not? Taking STRING of a string whilst making leading zeros - Joe Horn - 01-30-2018 02:28 PM

Warning #1: The output of STRING(X) depends on the current Number Format in Home Settings. For example, STRING(456) in Fixed 2 mode returns "456.00" which might not be what you want. To insure that whole numbers always get turned into strings without decimal places, use the optional second argument to specify the desired format regardless of the current setting. STRING(456,1) --> "456" (the 1 here means "use Standard number format").

Warning #2: In CAS programs, be sure to use the newer, smarter function STRING(), not its older, dumber sibling string(). Thankfully, Home always uses STRING().


RE: Bug or Not? Taking STRING of a string whilst making leading zeros - Didier Lachieze - 01-30-2018 03:00 PM

(01-30-2018 02:28 PM)Joe Horn Wrote:  Warning #1: The output of STRING(X) depends on the current Number Format in Home Settings.

Good Point ! I always forget it as I'm almost always in Standard number format.


RE: Bug or Not? Taking STRING of a string whilst making leading zeros - toml_12953 - 01-30-2018 03:25 PM

(01-30-2018 03:00 PM)Didier Lachieze Wrote:  
(01-30-2018 02:28 PM)Joe Horn Wrote:  Warning #1: The output of STRING(X) depends on the current Number Format in Home Settings.

Good Point ! I always forget it as I'm almost always in Standard number format.

Moi aussi. (Me too™)


RE: Bug or Not? Taking STRING of a string whilst making leading zeros - StephenG1CMZ - 01-30-2018 07:58 PM

Thanks for those tips - I was assuming STRING was cleverly turning whatever into a string and could leave "9" unchanged.
So far I have this for producing leading zeros (based on the above but handling 0 zeros):
Code:


 EXPORT NZEROS(NZ)
 //ONLY WORKS FOR NZ<12
 BEGIN
  RETURN IFTE(NZ>0,MID(STRING(10^NZ),2),"");
 END;
It only works with less than 12 zeros...
I am surprised there is no built-in for this.


RE: Bug or Not? Taking STRING of a string whilst making leading zeros - Didier Lachieze - 01-30-2018 08:16 PM

Here is a version without the limitation of NZ<12:
Code:
EXPORT NZEROS(NZ)
BEGIN
 RETURN CAS("tail(string(10^NZ))");
END;

(01-30-2018 02:28 PM)Joe Horn Wrote:  Warning #2: In CAS programs, be sure to use the newer, smarter function STRING(), not its older, dumber sibling string(). Thankfully, Home always uses STRING().
What's the difference between the two functions?


RE: Bug or Not? Taking STRING of a string whilst making leading zeros - Han - 01-30-2018 08:17 PM

Either make a "constant" string of more-than-enough 0's and append it to the front of your number, or create a function that will produce such a string by repeatedly adding a small string of zero's to itself and then append this to the front. Then simply "cut" the desired length using MID().


RE: Bug or Not? Taking STRING of a string whilst making leading zeros - StephenG1CMZ - 01-30-2018 08:48 PM

(01-30-2018 08:16 PM)Didier Lachieze Wrote:  Here is a version without the limitation of NZ<12:
Code:
EXPORT NZEROS(NZ)
BEGIN
 RETURN CAS("tail(string(10^NZ))");
END;

(01-30-2018 02:28 PM)Joe Horn Wrote:  Warning #2: In CAS programs, be sure to use the newer, smarter function STRING(), not its older, dumber sibling string(). Thankfully, Home always uses STRING().
What's the difference between the two functions?

Neat solution.
I am surprised that the obvious recursive solution is faster (and can recurse up to at least 1000 digits):
Code:

EXPORT ZEROS(NN)
 BEGIN
  IF NN>0 THEN
   RETURN "0"+ZEROS(NN-1);
  END;
  RETURN ""; 
 END;
I had expected that the recursive solution would be worse.


RE: Bug or Not? Taking STRING of a string whilst making leading zeros - toml_12953 - 01-30-2018 09:19 PM

(01-30-2018 08:17 PM)Han Wrote:  Either make a "constant" string of more-than-enough 0's and append it to the front of your number, or create a function that will produce such a string by repeatedly adding a small string of zero's to itself and then append this to the front. Then simply "cut" the desired length using MID().
Yup, that what the line I posted does. It works and is pretty easy to understand.


RE: Bug or Not? Taking STRING of a string whilst making leading zeros - Carlos295pz - 01-30-2018 09:36 PM

The recursive function may look like this:
Code:
EXPORT ZEROS(NZ)
BEGIN
   IFTE(NN,"0"+ZEROS(NZ-1),"")
END;

Speed may not be important for that code, but it may be better to use ITERATE instead of tail.
Code:
EXPORT ZEROS(NZ)
BEGIN
   ITERATE(X+"0",X,"0",NZ)
END;



RE: Bug or Not? Taking STRING of a string whilst making leading zeros - Jacob Wall - 01-31-2018 03:05 AM

Some interesting solutions I might not have thought of myself.

Here are two functions I've been using to left- or right-justify a string. Arguments are a string to be processed, the desired length of the resulting string, and the filler character, could be anything but probably 0 or space most common. T

Code:
StrLJust(str,len,spacer)
BEGIN
  LOCAL j,strdim:=DIM(str);
  IF len>strdim THEN
    FOR j FROM strdim TO len-1 DO
      str:=str+spacer;
    END;
  END;
  RETURN(str);
END;

StrRJust(str,len,spacer)
BEGIN
  LOCAL j,strdim:=DIM(str);
  IF len>strdim THEN
    FOR j FROM strdim TO len-1 DO
      str:=spacer+str;
    END;
  END;
  RETURN(str);
END;

But looking at the ITERATE command, this can definitely be made more compact:
Code:
StrLJust(str,len,spacer)
BEGIN
  RETURN(IFTE(DIM(str)<len,str+ITERATE(str+spacer,str,spacer,len-DIM(str)-1),str);
END;

StrLRJust(str,len,spacer)
BEGIN
  RETURN(IFTE(DIM(str)<len,ITERATE(str+spacer,str,spacer,len-DIM(str)-1)+str,str);
END;

Thanks Carlos! Have you made benchmark comparisons between FOR loop and ITERATE? Would be curious if one is faster than the other.