src/share/vm/runtime/sharedRuntimeMath.hpp

Thu, 31 Jul 2014 19:59:36 +0200

author
roland
date
Thu, 31 Jul 2014 19:59:36 +0200
changeset 7003
69ea58782b1a
parent 7002
a073be2ce5c2
permissions
-rw-r--r--

8054054: 8040121 is broken
Summary: C++ code pattern from 8040121 is incorrect
Reviewed-by: kvn

lfoltan@7000 1 /*
lfoltan@7000 2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
lfoltan@7000 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
lfoltan@7000 4 *
lfoltan@7000 5 * This code is free software; you can redistribute it and/or modify it
lfoltan@7000 6 * under the terms of the GNU General Public License version 2 only, as
lfoltan@7000 7 * published by the Free Software Foundation.
lfoltan@7000 8 *
lfoltan@7000 9 * This code is distributed in the hope that it will be useful, but WITHOUT
lfoltan@7000 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
lfoltan@7000 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
lfoltan@7000 12 * version 2 for more details (a copy is included in the LICENSE file that
lfoltan@7000 13 * accompanied this code).
lfoltan@7000 14 *
lfoltan@7000 15 * You should have received a copy of the GNU General Public License version
lfoltan@7000 16 * 2 along with this work; if not, write to the Free Software Foundation,
lfoltan@7000 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
lfoltan@7000 18 *
lfoltan@7000 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
lfoltan@7000 20 * or visit www.oracle.com if you need additional information or have any
lfoltan@7000 21 * questions.
lfoltan@7000 22 *
lfoltan@7000 23 */
lfoltan@7000 24
lfoltan@7000 25 #ifndef SHARE_VM_RUNTIME_SHAREDRUNTIMEMATH_HPP
lfoltan@7000 26 #define SHARE_VM_RUNTIME_SHAREDRUNTIMEMATH_HPP
lfoltan@7000 27
lfoltan@7000 28 #include <math.h>
lfoltan@7000 29
thartmann@7002 30 // Used to access the lower/higher 32 bits of a double
thartmann@7002 31 typedef union {
thartmann@7002 32 double d;
thartmann@7002 33 struct {
lfoltan@7000 34 #ifdef VM_LITTLE_ENDIAN
thartmann@7002 35 int lo;
thartmann@7002 36 int hi;
lfoltan@7000 37 #else
thartmann@7002 38 int hi;
thartmann@7002 39 int lo;
lfoltan@7000 40 #endif
thartmann@7002 41 } split;
thartmann@7002 42 } DoubleIntConv;
thartmann@7002 43
thartmann@7002 44 static inline int high(double d) {
roland@7003 45 DoubleIntConv x;
roland@7003 46 x.d = d;
thartmann@7002 47 return x.split.hi;
thartmann@7002 48 }
thartmann@7002 49
thartmann@7002 50 static inline int low(double d) {
roland@7003 51 DoubleIntConv x;
roland@7003 52 x.d = d;
thartmann@7002 53 return x.split.lo;
thartmann@7002 54 }
thartmann@7002 55
thartmann@7002 56 static inline void set_high(double* d, int high) {
roland@7003 57 DoubleIntConv conv;
roland@7003 58 conv.d = *d;
thartmann@7002 59 conv.split.hi = high;
thartmann@7002 60 *d = conv.d;
thartmann@7002 61 }
thartmann@7002 62
thartmann@7002 63 static inline void set_low(double* d, int low) {
roland@7003 64 DoubleIntConv conv;
roland@7003 65 conv.d = *d;
thartmann@7002 66 conv.split.lo = low;
thartmann@7002 67 *d = conv.d;
thartmann@7002 68 }
lfoltan@7000 69
lfoltan@7000 70 static double copysignA(double x, double y) {
roland@7003 71 DoubleIntConv convX;
roland@7003 72 convX.d = x;
thartmann@7002 73 convX.split.hi = (convX.split.hi & 0x7fffffff) | (high(y) & 0x80000000);
thartmann@7002 74 return convX.d;
lfoltan@7000 75 }
lfoltan@7000 76
lfoltan@7000 77 /*
lfoltan@7000 78 * ====================================================
lfoltan@7000 79 * Copyright (c) 1998 Oracle and/or its affiliates. All rights reserved.
lfoltan@7000 80 *
lfoltan@7000 81 * Developed at SunSoft, a Sun Microsystems, Inc. business.
lfoltan@7000 82 * Permission to use, copy, modify, and distribute this
lfoltan@7000 83 * software is freely granted, provided that this notice
lfoltan@7000 84 * is preserved.
lfoltan@7000 85 * ====================================================
lfoltan@7000 86 */
lfoltan@7000 87
lfoltan@7000 88 /*
lfoltan@7000 89 * scalbn (double x, int n)
lfoltan@7000 90 * scalbn(x,n) returns x* 2**n computed by exponent
lfoltan@7000 91 * manipulation rather than by actually performing an
lfoltan@7000 92 * exponentiation or a multiplication.
lfoltan@7000 93 */
lfoltan@7000 94
lfoltan@7000 95 static const double
lfoltan@7000 96 two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
lfoltan@7000 97 twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
lfoltan@7000 98 hugeX = 1.0e+300,
lfoltan@7000 99 tiny = 1.0e-300;
lfoltan@7000 100
thartmann@7002 101 static double scalbnA(double x, int n) {
lfoltan@7000 102 int k,hx,lx;
thartmann@7002 103 hx = high(x);
thartmann@7002 104 lx = low(x);
lfoltan@7000 105 k = (hx&0x7ff00000)>>20; /* extract exponent */
lfoltan@7000 106 if (k==0) { /* 0 or subnormal x */
lfoltan@7000 107 if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
lfoltan@7000 108 x *= two54;
thartmann@7002 109 hx = high(x);
lfoltan@7000 110 k = ((hx&0x7ff00000)>>20) - 54;
lfoltan@7000 111 if (n< -50000) return tiny*x; /*underflow*/
lfoltan@7000 112 }
lfoltan@7000 113 if (k==0x7ff) return x+x; /* NaN or Inf */
lfoltan@7000 114 k = k+n;
thartmann@7002 115 if (k > 0x7fe) return hugeX*copysignA(hugeX,x); /* overflow */
thartmann@7002 116 if (k > 0) { /* normal result */
thartmann@7002 117 set_high(&x, (hx&0x800fffff)|(k<<20));
thartmann@7002 118 return x;
thartmann@7002 119 }
lfoltan@7000 120 if (k <= -54) {
lfoltan@7000 121 if (n > 50000) /* in case integer overflow in n+k */
lfoltan@7000 122 return hugeX*copysignA(hugeX,x); /*overflow*/
lfoltan@7000 123 else return tiny*copysignA(tiny,x); /*underflow*/
lfoltan@7000 124 }
lfoltan@7000 125 k += 54; /* subnormal result */
thartmann@7002 126 set_high(&x, (hx&0x800fffff)|(k<<20));
lfoltan@7000 127 return x*twom54;
lfoltan@7000 128 }
lfoltan@7000 129
lfoltan@7000 130 #endif // SHARE_VM_RUNTIME_SHAREDRUNTIMEMATH_HPP

mercurial