Jump to content

Kahan summation: Difference between revisions

Rename Perl 6 -> Raku, alphabetize, minor clean-up
m (→‎{{header|Factor}}: calculate epsilon at parse time)
(Rename Perl 6 -> Raku, alphabetize, minor clean-up)
Line 194:
{{out}}<pre>Simple: 1.00000E +4 + 3.14159E +0 + 2.71828E +0 = 1.00058E +4
Kahan : 1.00000E +4 + 3.14159E +0 + 2.71828E +0 = 1.00059E +4</pre>
 
=={{header|AWK}}==
<lang AWK>
Line 273 ⟶ 274:
(a + b) + c = 0.999999940395
Kahan sum = 1.000000000000</pre>
 
=={{header|C sharp|C#}}==
<lang csharp>using System;
 
namespace KahanSummation {
class Program {
static float KahanSum(params float[] fa) {
float sum = 0.0f;
float c = 0.0f;
foreach (float f in fa) {
float y = f - c;
float t = sum + y;
c = (t - sum) - y;
sum = t;
}
 
return sum;
}
 
static float Epsilon() {
float eps = 1.0f;
while (1.0f + eps != 1.0f) eps /= 2.0f;
return eps;
}
 
static void Main(string[] args) {
float a = 1.0f;
float b = Epsilon();
float 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));
}
}
}</lang>
{{out}}
<pre>Epsilon = 1.110223E-16
(a + b) + c = 1
Kahan sum = 1</pre>
 
=={{header|C++}}==
Line 310 ⟶ 350:
{{out}}
<pre>Epsilon = 5.96046e-08
(a + b) + c = 1
Kahan sum = 1</pre>
 
=={{header|C#|C sharp}}==
<lang csharp>using System;
 
namespace KahanSummation {
class Program {
static float KahanSum(params float[] fa) {
float sum = 0.0f;
float c = 0.0f;
foreach (float f in fa) {
float y = f - c;
float t = sum + y;
c = (t - sum) - y;
sum = t;
}
 
return sum;
}
 
static float Epsilon() {
float eps = 1.0f;
while (1.0f + eps != 1.0f) eps /= 2.0f;
return eps;
}
 
static void Main(string[] args) {
float a = 1.0f;
float b = Epsilon();
float 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));
}
}
}</lang>
{{out}}
<pre>Epsilon = 1.110223E-16
(a + b) + c = 1
Kahan sum = 1</pre>
Line 1,133 ⟶ 1,134:
Voila!
See also http://keiapl.info/anec/#fuzz
 
=={{header|Java}}==
{{trans|Kotlin}}
Line 1,340 ⟶ 1,342:
(a + b) + c = 1.00000000
Kahan sum = 1.00000000</pre>
 
=={{header|PARI/GP}}==
No decimals here; the example below uses 64-bit binary arithmetic.
 
This is a ''partial solution'' only; I haven't found appropriate values that fail for normal addition. (Experimentation should produce these, in which case the existing code should work with the inputs changed.)
<lang parigp>Kahan(v)=my(s=0.,c=0.,y,t);for(i=1,#v,y=v[i]-c;t=s+y;c=t-s-y;s=t);s;
epsilon()=my(e=1.); while(e+1. != 1., e>>=1); e;
\p 19
e=epsilon();
Kahan([1.,e,-e])</lang>
{{out}}
<pre>%1 = 1.000000000000000000</pre>
 
=={{header|Objeck}}==
Line 1,397 ⟶ 1,387:
Kahan sum = 1
</pre>
 
=={{header|PARI/GP}}==
No decimals here; the example below uses 64-bit binary arithmetic.
 
This is a ''partial solution'' only; I haven't found appropriate values that fail for normal addition. (Experimentation should produce these, in which case the existing code should work with the inputs changed.)
<lang parigp>Kahan(v)=my(s=0.,c=0.,y,t);for(i=1,#v,y=v[i]-c;t=s+y;c=t-s-y;s=t);s;
epsilon()=my(e=1.); while(e+1. != 1., e>>=1); e;
\p 19
e=epsilon();
Kahan([1.,e,-e])</lang>
{{out}}
<pre>%1 = 1.000000000000000000</pre>
 
=={{header|Perl}}==
Line 1,426 ⟶ 1,428:
Simple sum: 0.9999999999999999
Kahan sum: 1.0000000000000000</pre>
 
=={{header|Perl 6}}==
{{trans|Python}}
Perl&nbsp;6 does not offer a fixed precision decimal. It ''does'' have IEEE 754 floating point numbers so let's try implementing the floating point option as shown in Python. Need to explicitly specify scientific notation numbers to force floating point Nums.
 
<lang perl6>constant ε = (1e0, */2e0 … *+1e0==1e0)[*-1];
 
sub kahan (*@nums) {
my $summ = my $c = 0e0;
for @nums -> $num {
my $y = $num - $c;
my $t = $summ + $y;
$c = ($t - $summ) - $y;
$summ = $t;
}
$summ
}
 
say 'Epsilon: ', ε;
 
say 'Simple sum: ', ((1e0 + ε) - ε).fmt: "%.16f";
 
say 'Kahan sum: ', kahan(1e0, ε, -ε).fmt: "%.16f";</lang>
{{out}}
<pre>Epsilon: 1.1102230246251565e-16
Simple sum: 0.9999999999999999
Kahan sum: 1.0000000000000000
</pre>
 
=={{header|Phix}}==
Line 1,928 ⟶ 1,902:
0.99999994f0
1.0f0</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
{{trans|Python}}
Perl&nbsp;6 does not offer a fixed precision decimal. It ''does'' have IEEE 754 floating point numbers so let's try implementing the floating point option as shown in Python. Need to explicitly specify scientific notation numbers to force floating point Nums.
 
<lang perl6>constant ε = (1e0, */2e0 … *+1e0==1e0)[*-1];
 
sub kahan (*@nums) {
my $summ = my $c = 0e0;
for @nums -> $num {
my $y = $num - $c;
my $t = $summ + $y;
$c = ($t - $summ) - $y;
$summ = $t;
}
$summ
}
 
say 'Epsilon: ', ε;
 
say 'Simple sum: ', ((1e0 + ε) - ε).fmt: "%.16f";
 
say 'Kahan sum: ', kahan(1e0, ε, -ε).fmt: "%.16f";</lang>
{{out}}
<pre>Epsilon: 1.1102230246251565e-16
Simple sum: 0.9999999999999999
Kahan sum: 1.0000000000000000
</pre>
 
=={{header|REXX}}==
Line 2,098 ⟶ 2,101:
[a,b,c].sum: 1.0
</pre>
 
=={{header|Scala}}==
===IEEE 754 Single precision 32-bit (JavaScript defaults to Double precision.)===
10,333

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.