Kahan summation: Difference between revisions
Content added Content deleted
(Added Gambas y True BASIC) |
(Grouping BASIC dialects) |
||
Line 396: | Line 396: | ||
=={{header|BASIC}}== |
=={{header|BASIC}}== |
||
==={{header|FreeBASIC}}=== |
|||
<syntaxhighlight lang="vbnet">Dim Shared As Double a, b, c |
|||
Function KahanSum (a As Double, b As Double, c As Double) As Double |
|||
Dim As Double sum = 0.0, i, y, t |
|||
c = 0.0 |
|||
For i = 1 To a |
|||
y = i - c |
|||
t = sum + y |
|||
c = (t - sum) - y |
|||
sum = t |
|||
Next i |
|||
Return sum |
|||
End Function |
|||
Function epsilon() As Double |
|||
Dim As Double eps = 1 |
|||
While (1 + eps <> 1) |
|||
eps /= 2 |
|||
Wend |
|||
Return eps |
|||
End Function |
|||
a = 1.0 |
|||
b = epsilon() |
|||
c = -b |
|||
Dim As Double s = (a + b) + c |
|||
Dim As Double k = KahanSum(a, b, c) |
|||
Dim As Double d = k - s |
|||
Print "Epsilon ="; b |
|||
Print "(a + b) + c ="; s |
|||
Print "Kahan sum ="; k |
|||
Print "Delta ="; d |
|||
Sleep</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Epsilon = 1.110223024625157e-016 |
|||
(a + b) + c = 0.9999999999999999 |
|||
Kahan sum = 1 |
|||
Delta = 1.110223024625157e-016 |
|||
</pre> |
|||
==={{header|FutureBasic}}=== |
|||
FB has proper decimal numbers supporting mantissas and exponents. But conversion to and from floating point numbers (or strings) makes it easier and more readable for this task to be completed with doubles as are many other examples here. |
|||
<syntaxhighlight lang="futurebasic"> |
|||
_elements = 3 |
|||
local fn Epsilon as double |
|||
double eps = 1.0 |
|||
while ( 1.0 + eps != 1.0 ) |
|||
eps = eps / 2.0 |
|||
wend |
|||
end fn = eps |
|||
local fn KahanSum( nums(_elements) as double, count as long ) as double |
|||
double sum = 0.0 |
|||
double c = 0.0 |
|||
double t, y |
|||
long i |
|||
for i = 0 to count - 1 |
|||
y = nums(i) - c |
|||
t = sum + y |
|||
c = (t - sum) - y |
|||
sum = t |
|||
next |
|||
end fn = sum |
|||
local fn DoKahan |
|||
double a = 1.0 |
|||
double b = fn Epsilon |
|||
double c = -b |
|||
double fa[_elements] |
|||
fa(0) = a : fa(1) = b : fa(2) = c |
|||
printf @"Epsilon = %.9e", b |
|||
printF @"(a + b) + c = %.9e", (a + b) + c |
|||
printf @"Kahan sum = %.9e", fn KahanSum( fa(0), 3 ) |
|||
printf @"Delta = %.9e", fn KahanSum( fa(0), 3 ) - ((a + b) + c) |
|||
end fn |
|||
fn DoKahan |
|||
HandleEvents</syntaxhighlight> |
|||
{{output}} |
|||
<pre> |
|||
Epsilon = 1.110223025e-16 |
|||
(a + b) + c = 1.000000000e+00 |
|||
Kahan sum = 1.000000000e+00 |
|||
Delta = 1.110223025e-16 |
|||
</pre> |
|||
==={{header|Gambas}}=== |
==={{header|Gambas}}=== |
||
{{trans|FreeBASIC}} |
{{trans|FreeBASIC}} |
||
Line 487: | Line 583: | ||
Kahan sum = 1 |
Kahan sum = 1 |
||
Delta = 1.110223e-16</pre> |
Delta = 1.110223e-16</pre> |
||
==={{header|Visual Basic .NET}}=== |
|||
{{trans|C#}} |
|||
<syntaxhighlight lang="vbnet">Module Module1 |
|||
Function KahanSum(ParamArray fa As Single()) As Single |
|||
Dim sum = 0.0F |
|||
Dim c = 0.0F |
|||
For Each f In fa |
|||
Dim y = f - c |
|||
Dim t = sum + y |
|||
c = (t - sum) - y |
|||
sum = t |
|||
Next |
|||
Return sum |
|||
End Function |
|||
Function Epsilon() As Single |
|||
Dim eps = 1.0F |
|||
While 1.0F + eps <> 1.0F |
|||
eps /= 2.0F |
|||
End While |
|||
Return eps |
|||
End Function |
|||
Sub Main() |
|||
Dim a = 1.0F |
|||
Dim b = Epsilon() |
|||
Dim c = -b |
|||
Console.WriteLine("Epsilon = {0}", b) |
|||
Console.WriteLine("(a + b) + c = {0}", (a + b) + c) |
|||
Console.WriteLine("Kahan sum = {0}", KahanSum(a, b, c)) |
|||
End Sub |
|||
End Module</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Epsilon = 1.110223E-16 |
|||
(a + b) + c = 1 |
|||
Kahan sum = 1</pre> |
|||
==={{header|Yabasic}}=== |
|||
{{trans|FreeBASIC}} |
|||
<syntaxhighlight lang="vbnet">a = 1.0 |
|||
b = epsilon() |
|||
c = -b |
|||
s = (a + b) + c |
|||
k = KahanSum(a, b, c) |
|||
d = k - s |
|||
print "Epsilon = ", b |
|||
print "(a + b) + c = ", s |
|||
print "Kahan sum = ", k |
|||
print "Delta = ", d |
|||
end |
|||
sub KahanSum (a, b, c) |
|||
sum = 0.0 |
|||
c = 0.0 |
|||
for i = 1 to a |
|||
y = i - c |
|||
t = sum + y |
|||
c = (t - sum) - y |
|||
sum = t |
|||
next i |
|||
return sum |
|||
end sub |
|||
sub epsilon() |
|||
eps = 1 |
|||
while (1 + eps <> 1) |
|||
eps = eps / 2.0 |
|||
wend |
|||
return eps |
|||
end sub</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Epsilon = 1.11022e-16 |
|||
(a + b) + c = 1 |
|||
Kahan sum = 1 |
|||
Delta = 1.11022e-16 |
|||
</pre> |
|||
=={{header|C}}== |
=={{header|C}}== |
||
Line 1,318: | Line 1,495: | ||
And this time, the compensated summation calculation comes out with one while the successive additions via a loop do not, as required. |
And this time, the compensated summation calculation comes out with one while the successive additions via a loop do not, as required. |
||
=={{header|FreeBASIC}}== |
|||
<syntaxhighlight lang="freebasic">Dim Shared As Double a, b, c |
|||
Function KahanSum (a As Double, b As Double, c As Double) As Double |
|||
Dim As Double sum = 0.0, i, y, t |
|||
c = 0.0 |
|||
For i = 1 To a |
|||
y = i - c |
|||
t = sum + y |
|||
c = (t - sum) - y |
|||
sum = t |
|||
Next i |
|||
Return sum |
|||
End Function |
|||
Function epsilon() As Double |
|||
Dim As Double eps = 1 |
|||
While (1 + eps <> 1) |
|||
eps /= 2 |
|||
Wend |
|||
Return eps |
|||
End Function |
|||
a = 1.0 |
|||
b = epsilon() |
|||
c = -b |
|||
Dim As Double s = (a + b) + c |
|||
Dim As Double k = KahanSum(a, b, c) |
|||
Dim As Double d = k - s |
|||
Print "Epsilon ="; b |
|||
Print "(a + b) + c ="; s |
|||
Print "Kahan sum ="; k |
|||
Print "Delta ="; d |
|||
Sleep</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Epsilon = 1.110223024625157e-016 |
|||
(a + b) + c = 0.9999999999999999 |
|||
Kahan sum = 1 |
|||
Delta = 1.110223024625157e-016 |
|||
</pre> |
|||
=={{header|FutureBasic}}== |
|||
FB has proper decimal numbers supporting mantissas and exponents. But conversion to and from floating point numbers (or strings) makes it easier and more readable for this task to be completed with doubles as are many other examples here. |
|||
<syntaxhighlight lang="futurebasic"> |
|||
_elements = 3 |
|||
local fn Epsilon as double |
|||
double eps = 1.0 |
|||
while ( 1.0 + eps != 1.0 ) |
|||
eps = eps / 2.0 |
|||
wend |
|||
end fn = eps |
|||
local fn KahanSum( nums(_elements) as double, count as long ) as double |
|||
double sum = 0.0 |
|||
double c = 0.0 |
|||
double t, y |
|||
long i |
|||
for i = 0 to count - 1 |
|||
y = nums(i) - c |
|||
t = sum + y |
|||
c = (t - sum) - y |
|||
sum = t |
|||
next |
|||
end fn = sum |
|||
local fn DoKahan |
|||
double a = 1.0 |
|||
double b = fn Epsilon |
|||
double c = -b |
|||
double fa[_elements] |
|||
fa(0) = a : fa(1) = b : fa(2) = c |
|||
printf @"Epsilon = %.9e", b |
|||
printF @"(a + b) + c = %.9e", (a + b) + c |
|||
printf @"Kahan sum = %.9e", fn KahanSum( fa(0), 3 ) |
|||
printf @"Delta = %.9e", fn KahanSum( fa(0), 3 ) - ((a + b) + c) |
|||
end fn |
|||
fn DoKahan |
|||
HandleEvents |
|||
</syntaxhighlight> |
|||
{{output}} |
|||
<pre> |
|||
Epsilon = 1.110223025e-16 |
|||
(a + b) + c = 1.000000000e+00 |
|||
Kahan sum = 1.000000000e+00 |
|||
Delta = 1.110223025e-16 |
|||
</pre> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
||
Line 2,816: | Line 2,893: | ||
With "down" and "floor" rounding, the Kahan sum is too low (10005.8), but any other rounding makes it correct (10005.9). |
With "down" and "floor" rounding, the Kahan sum is too low (10005.8), but any other rounding makes it correct (10005.9). |
||
The Associative largest-to-smallest sum is never correct: "up" and "ceiling" rounding make it too high, while the rest make it low. |
The Associative largest-to-smallest sum is never correct: "up" and "ceiling" rounding make it too high, while the rest make it low. |
||
=={{header|Visual Basic .NET}}== |
|||
{{trans|C#}} |
|||
<syntaxhighlight lang="vbnet">Module Module1 |
|||
Function KahanSum(ParamArray fa As Single()) As Single |
|||
Dim sum = 0.0F |
|||
Dim c = 0.0F |
|||
For Each f In fa |
|||
Dim y = f - c |
|||
Dim t = sum + y |
|||
c = (t - sum) - y |
|||
sum = t |
|||
Next |
|||
Return sum |
|||
End Function |
|||
Function Epsilon() As Single |
|||
Dim eps = 1.0F |
|||
While 1.0F + eps <> 1.0F |
|||
eps /= 2.0F |
|||
End While |
|||
Return eps |
|||
End Function |
|||
Sub Main() |
|||
Dim a = 1.0F |
|||
Dim b = Epsilon() |
|||
Dim c = -b |
|||
Console.WriteLine("Epsilon = {0}", b) |
|||
Console.WriteLine("(a + b) + c = {0}", (a + b) + c) |
|||
Console.WriteLine("Kahan sum = {0}", KahanSum(a, b, c)) |
|||
End Sub |
|||
End Module</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Epsilon = 1.110223E-16 |
|||
(a + b) + c = 1 |
|||
Kahan sum = 1</pre> |
|||
=={{header|V (Vlang)}}== |
=={{header|V (Vlang)}}== |
||
Line 2,986: | Line 3,024: | ||
Kahan sum = 00000000 3FF00000 |
Kahan sum = 00000000 3FF00000 |
||
</pre> |
</pre> |
||
=={{header|Yabasic}}== |
|||
{{trans|FreeBASIC}} |
|||
<syntaxhighlight lang="yabasic">sub KahanSum (a, b, c) |
|||
sum = 0.0 |
|||
c = 0.0 |
|||
for i = 1 to a |
|||
y = i - c |
|||
t = sum + y |
|||
c = (t - sum) - y |
|||
sum = t |
|||
next i |
|||
return sum |
|||
end sub |
|||
sub epsilon() |
|||
eps = 1 |
|||
while (1 + eps <> 1) |
|||
eps = eps / 2.0 |
|||
wend |
|||
return eps |
|||
end sub |
|||
a = 1.0 |
|||
b = epsilon() |
|||
c = -b |
|||
s = (a + b) + c |
|||
k = KahanSum(a, b, c) |
|||
d = k - s |
|||
print "Epsilon = ", b |
|||
print "(a + b) + c = ", s |
|||
print "Kahan sum = ", k |
|||
print "Delta = ", d |
|||
end</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Epsilon = 1.11022e-16 |
|||
(a + b) + c = 1 |
|||
Kahan sum = 1 |
|||
Delta = 1.11022e-16 |
|||
</pre> |
|||
=={{header|zkl}}== |
=={{header|zkl}}== |