lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi] MinGW-w64 anomaly?


From: Greg Chicares
Subject: [lmi] MinGW-w64 anomaly?
Date: Sun, 18 Dec 2016 14:28:46 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Icedove/45.4.0

Vadim--Could you please take a look at this? It's an extremely simplified
test case, but it's important for the way lmi performs rounding.

Apply the patch below [0] and run:
  make unit_tests unit_test_targets=sandbox_test.exe

Cross-compiling for msw on debian with MinGW-w64 gcc-4.9.1, I see:

Running sandbox_test:
f2():
   0.0000000001000000000000000000018377930496 1/10^10
   0.0000000001000000000000000000397031165002  10^-10

f3():
   0.0000000001000000000000000000018377930496 1/10^10
   0.0000000001000000000000000000018377930496  10^-10

What concerns me is the second of those four numbers: it's less accurate
than the other three. If an 80-byte register is being spilled to 64-byte
storage, I'd expect the result to be less accurate than this. I just
can't see any way to explain it.

I can work around this by taking the reciprocal of the product of N tens,
which seems always to be as accurate as the best case with std::pow(),
but I'd rather avoid that.

---------

[0] "the patch below":

----------8<----------8<----------8<----------8<----------8<----------
diff --git a/sandbox_test.cpp b/sandbox_test.cpp
index a146d0e..b7239af 100644
--- a/sandbox_test.cpp
+++ b/sandbox_test.cpp
@@ -23,8 +23,40 @@
 
 #include "test_tools.hpp"
 
+#include <cmath>
+#include <iomanip>
+#include <iostream>
+#include <ostream>
+
+void f2(long double r)
+{
+    int n = -10;
+    std::cout
+        << "f2():\n"
+        << std::fixed << std::setprecision(40)
+        << std::setw(45) << 1.0L / std::pow(r, -n) << " 1/10^10\n"
+        << std::setw(45) <<        std::pow(r,  n) << "  10^-10\n"
+        << std::endl
+        ;
+}
+
+void f3()
+{
+    long double r = 10.0L;
+    int n = -10;
+    std::cout
+        << "f3():\n"
+        << std::fixed << std::setprecision(40)
+        << std::setw(45) << 1.0L / std::pow(r, -n) << " 1/10^10\n"
+        << std::setw(45) <<        std::pow(r,  n) << "  10^-10\n"
+        << std::endl
+        ;
+}
+
 int test_main(int, char*[])
 {
+    f2(10.0L);
+    f3();
     return 0;
 }
 
---------->8---------->8---------->8---------->8---------->8----------



reply via email to

[Prev in Thread] Current Thread [Next in Thread]