Long multiplication: Difference between revisions

Content deleted Content added
Hout (talk | contribs)
m →‎version 1: added/changed comments, and whitespace, aligned some statements, optimized the calculation of the number of digits past the decimal points.
Line 3,826: Line 3,826:


Programming note: &nbsp; <big>&&</big> &nbsp; is REXX's &nbsp; '''exclusive or''' &nbsp; operand.
Programming note: &nbsp; <big>&&</big> &nbsp; is REXX's &nbsp; '''exclusive or''' &nbsp; operand.
<lang rexx>/*REXX program performs long multiplication on two numbers (without the "E").*/
<lang rexx>/*REXX program performs long multiplication on two numbers (without the "E"). */
numeric digits 3000 /*be able to handle gihugeic input #s. */
numeric digits 3000 /*be able to handle gihugeic input #s. */
parse arg x y . /*obtain the optional one or two #s. */
parse arg x y . /*obtain optional arguments from the CL*/
if x=='' then x=2**64 /*Not specified? Then use the default.*/
if x=='' | x=="." then x=2**64 /*Not specified? Then use the default.*/
if y=='' then y=x /* " " " " " " */
if y=='' | y=="," then y=x /* " " " " " " */
if x<0 && y<0 then sign='-' /*there only a single negative number? */
if x<0 && y<0 then sign= '-' /*there only a single negative number? */
else sign= /*no, then result sign must be positive*/
else sign= /*no, then result sign must be positive*/
xx=x; x=strip(x, 'T', .) /*remove any trailing decimal points. */
xx=x; x=strip(x, 'T', .); x1=left(x, 1) /*remove any trailing decimal points. */
yy=y; y=strip(y, 'T', .) /* " " " " ". */
yy=y; y=strip(y, 'T', .); y1=left(y, 1) /* " " " " " */
_=left(x,1); if _=='-' | _=='+' then x=substr(x,2) /*elide leading ± signs*/
if x1=='-' | x1=="+" then x=substr(x, 2) /*remove a leading ± sign. */
_=left(y,1); if _=='-' | _=='+' then y=substr(y,2) /* " " " " */
if y1=='-' | y1=="+" then y=substr(y, 2) /* " " " " " */
dp=0; Lx=length(x); Ly=length(y) /*get the lengths of the new X and Y. */
parse var x '.' xf; parse var y "." yf /*obtain the fractional part of X and Y*/
f=pos(., x); if f\==0 then dp= Lx-f /*calculate size of decimal fraction. */
#=length(xf || yf) /*#: digits past the decimal points (.)*/
f=pos(., y); if f\==0 then dp=dp+Ly-f /* " " " " " */
x=space( translate( x, , .), 0) /*remove decimal point if there is any.*/
x=space(translate(x, , .), 0) /*remove decimal point if there is any.*/
y=space( translate( y, , .), 0) /* " " " " " " " */
y=space(translate(y, , .), 0) /* " " " " " " " */
Lx=length(x); Ly=length(y) /*get the lengths of the new X and Y. */
Lx=length(x); Ly=length(y) /*get the lengths of the new X and Y. */
numeric digits max(digits(), Lx + Ly) /*use a new decimal digits precision.*/
$=0 /*$: is the product (so far). */
numeric digits max(digits(), Lx+Ly) /*use a new decimal digits precision.*/
$=0 /*P: is the product (so far). */
do j=Ly by -1 for Ly /*almost like REXX does it, ··· but no.*/
do j=Ly by -1 for Ly /*almost like REXX does it, ··· but no.*/
$=$ + ((x*substr(y, j, 1))copies(0, Ly-j) )
$=$ + ((x*substr(y, j, 1))copies(0, Ly-j) )
end /*j*/
end /*j*/
f=length($) - # /*does product has enough decimal digs?*/
f=length($)-dp /*does product has enough decimal digs?*/
if f<0 then $=copies(0, abs(f) + 1)$ /*Negative? Add leading 0s for INSERT.*/
say ' built─in:' xx "*" yy '──►' xx*yy
if f<0 then $=copies(0, abs(f)+1)$ /*Negative? Add leading 0s for INSERT.*/
say ' built─in:' xx '*' yy '──►' xx*yy
say 'long mult:' xx "*" yy '──►' sign || strip( insert(., $, length($) - #), 'T', .)
/*stick a fork in it, we're all done. */</lang>
say 'long mult:' xx '*' yy '──►' sign||strip(insert(.,$,length($)-dp),'T',.)
/*stick a fork in it, we're all done. */</lang>
'''output''' &nbsp; when using the default inputs:
'''output''' &nbsp; when using the default inputs:
<pre>
<pre>