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

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

mercurial