Non-decimal radices/Convert: Difference between revisions

→‎{{header|REXX}}: separated doc from program, added more error checking, added better error messages, add/changed comments, expanded support for larger numbers.
(→‎{{header|Ruby}}: Added example)
(→‎{{header|REXX}}: separated doc from program, added more error checking, added better error messages, add/changed comments, expanded support for larger numbers.)
Line 1,703:
=={{header|REXX}}==
Instead of writing two seperate routines, only one was written to handle both tasks.
<br><br>This routine was ripped out from a bigger version of mine that allowed any number as input, including decimal fractions (or whatever base) fractions.
<br><br>Illegal numerals/digits are detected as well as illegal (notor supportedunsupported) bases.
/*<lang> ┌────────────────────────────────────────────────────────────────────┐
<lang rexx>/*REXX program converts numbers from one base to another, from 2 ──► 90.*/
┌─┘ Input to this program (bases must be positive wholeintegers numbers> 1): └─┐
/*┌────────────────────────────────────────────────────────────────────┐
┌─┘ Input to this program (bases must be positive whole numbers): └─┐
│ │
x is required (it may have a sign).
toBase the base to convert X to.
inBase the base X is expressed in.
else sigX= /*no sign. */
│ If X has a leading sign, it is maintained (kept) after conversion. │
│ │
│ toBase or inBase can be a comma (,) which causes the default │
└─┐ of 10 to be used. The limits of bases are: 2 ──► 90. ┌─┘
└────────────────────────────────────────────────────────────────────┘*</lang>
<lang rexx>/*REXX programpgm converts numbersintegers from one base to another, from (base 2 ──► 90). */
@abc = 'abcdefghijklmnopqrstuvwxyz' /*the lowercase (Latin) alphabet. */
@abcU=@abc; upper @abcU /*go whole hog and extend 'em. */
@@@=0123456789||parse upper var @abc||@abcU @abcU /*prefixuppercase 'ema withversion numericof digits @abc. */
@@ = 0123456789 || @abc || @abcU /*prefix 'em with numeric digits.*/
@@@ =@ @@'<>[]{}()?~!@#$%^&*_=|\/;:¢¬≈' /*add some special chars as well.*/
/*special chars must be viewable.*/
numeric digits 1000 /*what da[↑] all chars hey,must supportbe gihugeics.viewable*/
maxB=length(@@@) numeric digits 3000 /*maxwhat baseda (radix)hey, supportedsupport heregihugeics.*/
parsemaxB=length(@@) arg x toB inB 1 ox . /*get a number, /*max base toBase,(radix) supported inBasehere*/
ifparse toB==''arg |x toB==',' inB then1 toB=10ox . 1 sigX 2 x2 . /*ifget: skipped3 args, assume defaultorigX, (10)sign···*/
if inBpos(sigX,"+-")\==''0 | inBthen x==','x2 then inB=10 /*Does " X have "a leading sign? " " " */
if inB<2 | inb>maxB then call erb 'inBase',inB else sigX= /*badNope. boy inBaseNo leading sign for X. */
if toB<2x=='' | tob>maxB then call erb 'toBase',toB then call erm /*if "no X number, " issue toBaseerror.*/
if xtoB=='' | toB=="," then call erm toB=10 /*if "skipped, assume default " number.(10)*/
if inB=='' | inB=="," then inB=10 /* " " " " " */
sigX=left(x,1); if pos(sigX,"-+")\==0 then x=substr(x,2) /*X has sign?*/
if inB<2 | inb>maxB | \datatype(inB,'W') then call erb 'inBase ' inB
else sigX= /*no sign. */
if toB<2 | toB>maxB | \datatype(toB,'W') then call erb 'toBase ' toB
#=0; do j=1 for length(x) /*convert X, base inB ──► base 10*/
#=0 _=substr(x,j,1) /*pick off a "digit" from /*result of converted X. (base 10)*/
vdo j=pos(_,@@@) 1 for length(x) /*getconvert theX, valuebase ofinB this──► "digit".base 10*/
if v?==0substr(x,j,1) | v>inB then call erd x,j,inB /*illegalpick "off a numeral/digit"? from X*/
#_=#*inB+v-1pos(?, @@) /*constructcalculate newthis num,numeral's dig by digvalue. */
endif _==0 | _>inB then call erd x /*j_ character an illegal numeral?*/
#=#*inB+_-1 /*build a new number, dig by dig.*/
 
y=; do end /*j*/ while # >= toB /*convert #,[↑] base 10this ──►also baseverifies toBdigits*/
y= y=substr(@@@,(#//toB)+1,1)y /*construct the outputvalue number.of X in base B. */
do #=#%toB while # >= toB /*...convert and#, whittlebase 10 #──► base down also. toB*/
y=substr(@@, (#//toB)+1, end 1)y /*whileconstruct the output number. #>-toB*/
#=#%toB /*··· and whittle # down also. */
 
y=sigX || substr(@@@,#+1,1)y end /*while*/ /*prepend the[↑] signprocess ifleaves ita existed.residual*/
/*special chars[↓] must be viewable. Y is the residual*/
say ox "(base" inB')' center('is',20) y "(base" toB')' /*show & tell.*/
y=sigX || substr(@@, #+1, 1)y /*prepend the sign if it existed.*/
say ox "(base" inB')' center('is',20) y "(base" toB')' /*show & tell.*/
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────one─liner subroutines───────────────*/
/*──────────────────────────────────error subroutines───────────────────*/
erb: call ser; say 'illegal' arg(21) "base:", arg(1) "it must be in the range: 2──►" maxB
erd: call ser; say 'illegal "digit/numeral ['?"] in': x":" _ x
erm: call ser; say 'no argument specified.'
ser: say; say '*** error! ***'; say arg(1); exit 13</lang>
'''output''' when input is (maximum positive integer in a signed 32-bit word): <tt> 7fffffff , 16 </tt>
<pre>