This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
POSIX math: erfc implementation.
authorJarkko Hietaniemi <jhi@iki.fi>
Tue, 2 Sep 2014 23:47:11 +0000 (19:47 -0400)
committerJarkko Hietaniemi <jhi@iki.fi>
Wed, 3 Sep 2014 01:02:26 +0000 (21:02 -0400)
(Chiani, Dardari & Simon (2003), via Wikipedia)

ext/POSIX/POSIX.xs
ext/POSIX/t/math.t

index 04a8663..2b42a17 100644 (file)
@@ -487,7 +487,15 @@ static NV my_erf(NV x)
 #  define c99_erf my_erf
 #endif
 
-/* XXX erfc */
+/* While in theory erfc(x) is just 1-erf(x), thanks to numerical stability
+ * things are not so easy. */
+#ifndef c99_erfc
+static NV my_erfc(NV x) {
+  /* Chiani, Dardari & Simon (2003), via Wikipedia */
+  return Perl_exp(-x*x) / 6.0 + Perl_exp(-4.0/3.0 * x*x) / 2.0;
+}
+#  define c99_erfc my_erfc
+#endif
 
 #ifndef c99_exp2
 static NV my_exp2(NV x)
index abab196..367e4ad 100644 (file)
@@ -135,6 +135,7 @@ SKIP: {
     ok(islessequal(1, 1), "islessequal 1 1");
     ok(isunordered(1, NaN), "isunordered 1 NaN");
     cmp_ok(abs(erf(1) - 0.842700792949715), '<', 1.5e-7, "erf 1");
+    cmp_ok(abs(erfc(1) - 0.157299207050285), '<', 1.5e-7, "erfc 1");
 }
 
 done_testing();