Kahan summation: Difference between revisions

m
→‎{{header|REXX}}: added/changed comments and whitespace, changed indentations, used one fence, used output templates.
m (→‎{{header|PARI/GP}}: Removed superfluous right brace from heading)
m (→‎{{header|REXX}}: added/changed comments and whitespace, changed indentations, used one fence, used output templates.)
Line 1,356:
<br>of &nbsp; '''30''' &nbsp; (decimal digits) was chosen. &nbsp; The default precision for REXX is &nbsp; '''9''' &nbsp; decimal digits.
===vanilla version===
<lang rexx>/*REXX program demonstrates simple addition versus using Kahan summation algorithm. */
numeric digits 6 /*use numericsix (decimal) digits=6 for precision.*/
call show 10000.0, 3.14169, 2.71828 /*invoke SHOW to sum and& display numbers.*/
numeric digits 30 /*from now on, use 30 decimal digits.*/
 
epsilon=1.0
numeric digits 30
do while 1+epsilon \= 1 /*keep looping 'til we can't add unity.*/
epsilon=1.0
epsilon=epsilon / 2 do while 1.0+epsilon \= 1 /*halve the value of epsilon variable.0*/
end epsilon=epsilon / 2.0*while*/
say end /*whiledisplay a blank line before the fence*/
say; say copies('▒', 70); say /*display a fence, then a blank line. */
 
call show 1.0, epsilon, -epsilon /*invoke SHOW to sum and& display numbers.*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────KAHAN subroutine────────────────────*/
kahan: procedure; sum $=0; c=0; do j=1 for arg() /*perform for each argument. */
do j=1 for y=arg(j) - c /*dosubtract for eachC arg from argument.*/
y t=arg(j)-c$ + y /*subuse Ca fromtemporary argsum (T). */
t c=sum+yt - $ - y /*usecompute athe tempvalue sumof C. */
c $=(t-sum)-y /*sameredefine as:the t-sum-y ($). */
sum=t end /*define the sum. j*/
return sum$
end /*j*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
return sum
show: procedure; parse arg a,b,c /*obtain the arguments. */
/*──────────────────────────────────SHOW subroutine─────────────────────*/
show: procedure; parse arg a,b,c say 'decimal digits =' digits() /*obtainshow number of thedecimal args.digs*/
say 'decimal digits a = ' digits() left('', a>=0) a /*showdisplay # dec digsA justified. */
say ' ab = ' left('', ab>=0) a b /* " B " /*show A justified*/
say ' bc = ' left('', bc>=0) b c /* " /* " BC " */
say ' c = ' say left('', c>=0)simple summation of a,b,c = ' a+b+c /*compute simple " C " summation. */
say 'simpleKahan summation of a,b,c = ' kahan(a+,b)+,c ) /*samesum asvia Kahan a+b+c summation. */
return</lang>
say 'Kahan summation of a,b,c = ' kahan(a,b,c) /*sum via Kahan. */
'''{{out|output'''|text=&nbsp; using PC/REXX and also Personal REXX:}}
say; say copies('▒',70); say /*display a fence.*/
return</lang>
Output note: &nbsp; This is a work in progress and attempts are being made to determine a suitable/workable epsilon.
 
'''output''' using PC/REXX and also Personal REXX:
<pre>
decimal digits = 6
Line 1,406 ⟶ 1,402:
simple summation of a,b,c = 1.00000000000000000000000000000
Kahan summation of a,b,c = 1.00000000000000000000000000000
 
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
</pre>
'''{{out|output'''|text=&nbsp; using R4 and also ROO:}}
<pre>
decimal digits = 6
Line 1,426 ⟶ 1,420:
simple summation of a,b,c = 0.999999999999999999999999999997
Kahan summation of a,b,c = 1.00000000000000000000000000000
 
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
</pre>
'''{{out|output'''|text=&nbsp; using Regina 3.3 and earlier:}}
<pre>
decimal digits = 6
Line 1,446 ⟶ 1,438:
simple summation of a,b,c = 0.999999999999999999999999999997
Kahan summation of a,b,c = 1.00000000000000000000000000000
 
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
</pre>
'''{{out|output'''|text=&nbsp; using Regina 3.4 and later &nbsp; (latest at this time is 3.9.01):}}
<pre>
decimal digits = 6
Line 1,466 ⟶ 1,456:
simple summation of a,b,c = 1.00000000000000000000000000000
Kahan summation of a,b,c = 1.00000000000000000000000000000
 
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
</pre>
 
===tweaked version===
The following tweaked REXX version causes Regina (3.4 and later) to work properly.
<lang rexx>/*REXX program demonstrates simple addition versus using Kahan summation algorithm. */
numeric digits 6 /*use numericsix (decimal) digits=6 for precision.*/
call show 10000.0, 3.14169, 2.71828 /*invoke SHOW to sum and& display numbers.*/
numeric digits 30 /*from now on, use 30 decimal digits.*/
 
epsilon=1.0
numeric digits 30
do while 1+epsilon \= 1 /*keep looping 'til we can't add unity.*/
epsilon=1.0
epsilon=epsilon / 2 do while 1.0+epsilon \= 1 /*halve the value of epsilon variable.0*/
end epsilon=epsilon / 2.0*while*/
say end /*whiledisplay a blank line before the fence*/
say copies('▒', 70); say /*display [↓]a fence, forthen Reginaa 3blank line.4 and later.*/
numeric digits digits()+2 /*bump the[↓] precision byfor 2Regina digitsREXX 3.4 and later. */
numeric digits digits()+2 /*bump the precision by two dec digits.*/
call show 1.0, epsilon, -epsilon /*invoke SHOW to sum and display.*/
exit call show 1.0, epsilon, -epsilon /*stickinvoke aSHOW forkto insum it,& we'redisplay donenumbers.*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────KAHAN subroutine────────────────────*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
kahan: procedure; sum=0; c=0
kahan: procedure; $=0; c=0; do j=1 for arg() /*doperform for each argargument. */
y=arg(j) - c /*subsubtract C from argargument. */
t=sum$ + y /*use a temptemporary sum (T). */
c=(t -sum) $ - y /*samecompute the value of C. as: t-sum-y*/
sum $=t /*defineredefine the sum ($). */
end /*j*/
return sum$
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────SHOW subroutine─────────────────────*/
show: procedure; parse arg a,b,c /*obtain the argsarguments. */
say 'decimal digits =' digits() /*show #number decof decimal digs.*/
say ' a = ' left('', a>=0) a /*display A justified. /*show A justified*/
say ' b = ' left('', b>=0) b b /* " /* " B " */
say ' c = ' left('', c>=0) c c /* " /* " C " */
say 'simple summation of a,b,c = ' (a+b)+c a+b+c /*same ascompute simple a+b+csummation. */
say 'Kahan summation of a,b,c = ' kahan(a,b,c) /*sum via Kahan summation. */
return</lang>
say; say copies('▒',70); say /*display a fence.*/
'''{{out|output'''|text=&nbsp; forusing Regina 3.4 and also for later versions:}}
return</lang>
'''output''' for Regina 3.4 and later versions:
<pre>
decimal digits = 6
Line 1,521 ⟶ 1,508:
simple summation of a,b,c = 1.0000000000000000000000000000001
Kahan summation of a,b,c = 1.0000000000000000000000000000000
 
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
</pre>
'''output''' for ooRexx: