On 2017/3/24 23:08, Jeroen Ooms wrote:
I was able to reproduce the problem on msys2 with gcc 6.3:
#include <iostream>
#include <cmath>
#include <complex>
int main(){
std::cout << std::fixed;
std::complex<double> z(356, 0);
std::cout << "tanh" << z << " = " << std::tanh(z)
<< " (tanh(356) = " << std::tanh(356) << ")\n";
}
On Linux / OS-X we get:
tanh(356.000000,0.000000) = (1.000000,-0.000000) (tanh(356) = 1.000000)
But on Windows we get:
tanh(356.000000,0.000000) = (nan,0.000000) (tanh(356) = 1.000000)
After a little investigation the problem is located here:
In mingw-w64-crt\complex\ctanh.def.h:
__FLT_ABI(sincos) (__FLT_CST(2.0) * __imag__ z, &s, &c);
d = (__FLT_ABI(cosh) (__FLT_CST(2.0) * __real__ z) + c);
if (d == __FLT_CST(0.0))
{
__complex__ __FLT_TYPE ez = __FLT_ABI(cexp) (z);
__complex__ __FLT_TYPE emz = __FLT_ABI(cexp) (-z);
return (ez - emz) / (ez + emz);
}
__real__ ret = __FLT_ABI(sinh) (__FLT_CST(2.0) * __real__ z) / d;
Given `__real__ z` is 356, `cosh(712)` is called, which yields positive
infinity. Since it doesn't compare equal with zero, the `if` branch is
not taken and the result of `sinh(712)`, which is also positive
infinity, is divided by the previous result, yielding a NaN.
In the code above `ret` is normally set to `sinh(2 * __real__ z) /
cosh(2 * __real__ z)`. Acknowledging the fact that both can be NaNs we
can replace it with `tanh(2 * __real__ z)` directly ({sin,cos,tan}h
functions are part of MSVCRT). The attached patch should fix the problem.
I am not a mathematician, though. So please correct me.
--
Best regards,
LH_Mouse
From a46cc6ea45467cad2b0669417fdbe7afed78dade Mon Sep 17 00:00:00 2001
From: Liu Hao <[email protected]>
Date: Fri, 24 Mar 2017 23:49:39 +0800
Subject: [PATCH] Quick fix for ctanh() functions.
Signed-off-by: Liu Hao <[email protected]>
---
mingw-w64-crt/complex/ctanh.def.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mingw-w64-crt/complex/ctanh.def.h
b/mingw-w64-crt/complex/ctanh.def.h
index 11a18364..c36b75c7 100644
--- a/mingw-w64-crt/complex/ctanh.def.h
+++ b/mingw-w64-crt/complex/ctanh.def.h
@@ -88,7 +88,7 @@ __FLT_ABI(ctanh) (__FLT_TYPE __complex__ z)
return (ez - emz) / (ez + emz);
}
- __real__ ret = __FLT_ABI(sinh) (__FLT_CST(2.0) * __real__ z) / d;
+ __real__ ret = __FLT_ABI(tanh) (__FLT_CST(2.0) * __real__ z);
__imag__ ret = s / d;
return ret;
}
--
2.12.0
From a46cc6ea45467cad2b0669417fdbe7afed78dade Mon Sep 17 00:00:00 2001
From: Liu Hao <[email protected]>
Date: Fri, 24 Mar 2017 23:49:39 +0800
Subject: [PATCH] Quick fix for ctanh() functions.
Signed-off-by: Liu Hao <[email protected]>
---
mingw-w64-crt/complex/ctanh.def.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mingw-w64-crt/complex/ctanh.def.h
b/mingw-w64-crt/complex/ctanh.def.h
index 11a18364..c36b75c7 100644
--- a/mingw-w64-crt/complex/ctanh.def.h
+++ b/mingw-w64-crt/complex/ctanh.def.h
@@ -88,7 +88,7 @@ __FLT_ABI(ctanh) (__FLT_TYPE __complex__ z)
return (ez - emz) / (ez + emz);
}
- __real__ ret = __FLT_ABI(sinh) (__FLT_CST(2.0) * __real__ z) / d;
+ __real__ ret = __FLT_ABI(tanh) (__FLT_CST(2.0) * __real__ z);
__imag__ ret = s / d;
return ret;
}
--
2.12.0
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public