Piotr Caban : msvcrt: Import jn implementation from musl.

Alexandre Julliard julliard at winehq.org
Thu Apr 29 16:38:32 CDT 2021


Module: wine
Branch: master
Commit: 0a105999a2807d2649800399d2551dd976b24279
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=0a105999a2807d2649800399d2551dd976b24279

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Thu Apr 29 17:06:22 2021 +0200

msvcrt: Import jn implementation from musl.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 configure             |   1 -
 configure.ac          |   1 -
 dlls/msvcrt/math.c    | 128 ++++++++++++++++++++++++++++++++++++++++++++++++--
 dlls/msvcrt/unixlib.c |  14 ------
 dlls/msvcrt/unixlib.h |   1 -
 include/config.h.in   |   3 --
 6 files changed, 125 insertions(+), 23 deletions(-)

diff --git a/configure b/configure
index 3c12aa85227..33e79ad04a4 100755
--- a/configure
+++ b/configure
@@ -19631,7 +19631,6 @@ for ac_func in \
 	expm1f \
 	fma \
 	fmaf \
-	jn \
 	lgamma \
 	lgammaf \
 	llrint \
diff --git a/configure.ac b/configure.ac
index 65661d89263..550da301100 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2674,7 +2674,6 @@ AC_CHECK_FUNCS(\
 	expm1f \
 	fma \
 	fmaf \
-	jn \
 	lgamma \
 	lgammaf \
 	llrint \
diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c
index aa5f4b1af7b..019fb836c07 100644
--- a/dlls/msvcrt/math.c
+++ b/dlls/msvcrt/math.c
@@ -2912,11 +2912,133 @@ double CDECL _j1(double x)
 
 /*********************************************************************
  *		_jn (MSVCRT.@)
+ *
+ * Copied from musl: src/math/jn.c
  */
-double CDECL _jn(int n, double num)
+double CDECL _jn(int n, double x)
 {
-  /* FIXME: errno handling */
-  return unix_funcs->jn( n, num );
+    static const double invsqrtpi = 5.64189583547756279280e-01;
+
+    unsigned int ix, lx;
+    int nm1, i, sign;
+    double a, b, temp;
+
+    ix = *(ULONGLONG*)&x >> 32;
+    lx = *(ULONGLONG*)&x;
+    sign = ix >> 31;
+    ix &= 0x7fffffff;
+
+    if ((ix | (lx | -lx) >> 31) > 0x7ff00000) /* nan */
+        return x;
+
+    if (n == 0)
+        return _j0(x);
+    if (n < 0) {
+        nm1 = -(n + 1);
+        x = -x;
+        sign ^= 1;
+    } else {
+        nm1 = n-1;
+    }
+    if (nm1 == 0)
+        return j1(x);
+
+    sign &= n;  /* even n: 0, odd n: signbit(x) */
+    x = fabs(x);
+    if ((ix | lx) == 0 || ix == 0x7ff00000)  /* if x is 0 or inf */
+        b = 0.0;
+    else if (nm1 < x) {
+        if (ix >= 0x52d00000) { /* x > 2**302 */
+            switch(nm1 & 3) {
+            case 0:
+                temp = -cos(x) + sin(x);
+                break;
+            case 1:
+                temp = -cos(x) - sin(x);
+                break;
+            case 2:
+                temp =  cos(x) - sin(x);
+                break;
+            default:
+                temp =  cos(x) + sin(x);
+                break;
+            }
+            b = invsqrtpi * temp / sqrt(x);
+        } else {
+            a = _j0(x);
+            b = _j1(x);
+            for (i = 0; i < nm1; ) {
+                i++;
+                temp = b;
+                b = b * (2.0 * i / x) - a; /* avoid underflow */
+                a = temp;
+            }
+        }
+    } else {
+        if (ix < 0x3e100000) { /* x < 2**-29 */
+            if (nm1 > 32)  /* underflow */
+                b = 0.0;
+            else {
+                temp = x * 0.5;
+                b = temp;
+                a = 1.0;
+                for (i = 2; i <= nm1 + 1; i++) {
+                    a *= (double)i; /* a = n! */
+                    b *= temp;      /* b = (x/2)^n */
+                }
+                b = b / a;
+            }
+        } else {
+            double t, q0, q1, w, h, z, tmp, nf;
+            int k;
+
+            nf = nm1 + 1.0;
+            w = 2 * nf / x;
+            h = 2 / x;
+            z = w + h;
+            q0 = w;
+            q1 = w * z - 1.0;
+            k = 1;
+            while (q1 < 1.0e9) {
+                k += 1;
+                z += h;
+                tmp = z * q1 - q0;
+                q0 = q1;
+                q1 = tmp;
+            }
+            for (t = 0.0, i = k; i >= 0; i--)
+                t = 1 / (2 * (i + nf) / x - t);
+            a = t;
+            b = 1.0;
+            tmp = nf * log(fabs(w));
+            if (tmp < 7.09782712893383973096e+02) {
+                for (i = nm1; i > 0; i--) {
+                    temp = b;
+                    b = b * (2.0 * i) / x - a;
+                    a = temp;
+                }
+            } else {
+                for (i = nm1; i > 0; i--) {
+                    temp = b;
+                    b = b * (2.0 * i) / x - a;
+                    a = temp;
+                    /* scale b to avoid spurious overflow */
+                    if (b > 0x1p500) {
+                        a /= b;
+                        t /= b;
+                        b  = 1.0;
+                    }
+                }
+            }
+            z = j0(x);
+            w = j1(x);
+            if (fabs(z) >= fabs(w))
+                b = t * z / b;
+            else
+                b = t * w / a;
+        }
+    }
+    return sign ? -b : b;
 }
 
 /*********************************************************************
diff --git a/dlls/msvcrt/unixlib.c b/dlls/msvcrt/unixlib.c
index 597d0ed7f64..c5e62613940 100644
--- a/dlls/msvcrt/unixlib.c
+++ b/dlls/msvcrt/unixlib.c
@@ -401,19 +401,6 @@ static float CDECL unix_hypotf(float x, float y)
     return hypotf( x, y );
 }
 
-/*********************************************************************
- *      jn
- */
-static double CDECL unix_jn(int n, double num)
-{
-#ifdef HAVE_JN
-    return jn(n, num);
-#else
-    FIXME("not implemented\n");
-    return 0;
-#endif
-}
-
 /*********************************************************************
  *      ldexp
  */
@@ -1001,7 +988,6 @@ static const struct unix_funcs funcs =
     unix_frexpf,
     unix_hypot,
     unix_hypotf,
-    unix_jn,
     unix_ldexp,
     unix_lgamma,
     unix_lgammaf,
diff --git a/dlls/msvcrt/unixlib.h b/dlls/msvcrt/unixlib.h
index 21caa036498..48fc075d530 100644
--- a/dlls/msvcrt/unixlib.h
+++ b/dlls/msvcrt/unixlib.h
@@ -57,7 +57,6 @@ struct unix_funcs
     float           (CDECL *frexpf)(float x, int *exp);
     double          (CDECL *hypot)(double x, double y);
     float           (CDECL *hypotf)(float x, float y);
-    double          (CDECL *jn)(int n, double num);
     double          (CDECL *ldexp)(double x, int exp);
     double          (CDECL *lgamma)(double x);
     float           (CDECL *lgammaf)(float x);
diff --git a/include/config.h.in b/include/config.h.in
index 266d8cec8d9..197d5c4b5f7 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -288,9 +288,6 @@
 /* Define to 1 if you have the `isnan' function. */
 #undef HAVE_ISNAN
 
-/* Define to 1 if you have the `jn' function. */
-#undef HAVE_JN
-
 /* Define to 1 if you have the <jpeglib.h> header file. */
 #undef HAVE_JPEGLIB_H
 




More information about the wine-cvs mailing list