Kahan summation: Difference between revisions
Grouping BASIC dialects
(Added Dart) |
(Grouping BASIC dialects) |
||
(One intermediate revision by the same user not shown) | |||
Line 393:
(a+b)+c = 0.9999999999999999
Kahan sum = 1.0000000000000000
</pre>
=={{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}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="vbnet">Public a As Float
Public b As Float
Public c As Float
Function KahanSum(a As Float, b As Float, c As Float) As Float
Dim sum As Float = 0.0
Dim i As Float, y As Float, t As Float
c = 0.0
For i = 1 To a
y = i - c
t = sum + y
c = (t - sum) - y
sum = t
Next
Return sum
End Function
Function epsilon() As Float
Dim eps As Float = 1
While (1 + eps <> 1)
eps /= 2
Wend
Return eps
End Function
Public Sub Main()
a = 1.0
b = epsilon()
c = -b
Dim s As Float = (a + b) + c
Dim k As Float = KahanSum(a, b, c)
Dim d As Float = k - s
Print "Epsilon = "; b
Print "(a + b) + c = "; s
Print "Kahan sum = "; k
Print "Delta = "; d
End</syntaxhighlight>
{{out}}
<pre>Epsilon = 1,11022302462516E-16
(a + b) + c = 1
Kahan sum = 1
Delta = 1,11022302462516E-16</pre>
==={{header|True BASIC}}===
<syntaxhighlight lang="qbasic">
FUNCTION epsilon
LET eps = 1
DO while (1+eps <> 1)
LET eps = eps/2
LOOP
LET epsilon = eps
END FUNCTION
FUNCTION kahansum(a, b, c)
LET sum = 0
LET c = 0
FOR i = 1 to a
LET y = i-c
LET t = sum+y
LET c = (t-sum)-y
LET sum = t
NEXT i
LET kahansum = sum
END FUNCTION
LET a = 1
LET b = epsilon
LET c = -b
LET s = (a+b)+c
LET k = kahansum(a, b, c)
LET d = k-s
PRINT "Epsilon ="; b
PRINT "(a + b) + c ="; s
PRINT "Kahan sum ="; k
PRINT "Delta ="; d
END</syntaxhighlight>
{{out}}
<pre>Epsilon = 1.110223e-16
(a + b) + c = 1.
Kahan sum = 1
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>
Line 1,225 ⟶ 1,495:
And this time, the compensated summation calculation comes out with one while the successive additions via a loop do not, as required.
=={{header|Go}}==
Line 2,723 ⟶ 2,893:
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.
=={{header|V (Vlang)}}==
Line 2,893 ⟶ 3,024:
Kahan sum = 00000000 3FF00000
</pre>
=={{header|zkl}}==
|