OSDN Git Service

* java/lang/Double.java (doubleToRawLongBits): Now native.
[pf3gnuchains/gcc-fork.git] / libjava / java / lang / natDouble.cc
1 // natDouble.cc - Implementation of java.lang.Double native methods.
2
3 /* Copyright (C) 1998, 1999, 2000, 2001  Free Software Foundation
4
5    This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10
11 #include <config.h>
12
13 #if HAVE_ALLOCA_H
14 #include <alloca.h>
15 #endif
16
17 #include <stdlib.h>
18
19 #include <gcj/cni.h>
20 #include <java/lang/String.h>
21 #include <java/lang/Double.h>
22 #include <java/lang/NumberFormatException.h>
23 #include <jvm.h>
24
25 #include <stdio.h>
26 #include <string.h>
27
28 #include "fdlibm.h"
29
30 union u
31 {
32   jlong l;
33   jdouble d;
34 };
35
36 jlong 
37 java::lang::Double::doubleToLongBits(jdouble value)
38 {
39   union u u;
40   u.d = value;
41   
42   jlong e = u.l & 0x7ff0000000000000LL;
43   jlong f = u.l & 0x000fffffffffffffLL;
44
45   if (e == 0x7ff0000000000000LL && f != 0L)
46     u.l = 0x7ff8000000000000LL;
47
48   return u.l;
49 }
50
51 jlong 
52 java::lang::Double::doubleToRawLongBits(jdouble value)
53 {
54   union u u;
55   u.d = value;
56   return u.l;
57 }
58
59 jdouble 
60 java::lang::Double::longBitsToDouble(jlong bits)
61 {
62   union u u;
63   u.l = bits;
64   return u.d;
65 }
66
67 jstring 
68 java::lang::Double::toString(jdouble value, jboolean isFloat)
69 {
70   if (isNaN (value))
71     return JvNewStringLatin1 ("NaN", sizeof ("NaN") - 1);
72     
73   if (value == POSITIVE_INFINITY)
74     return JvNewStringLatin1 ("Infinity", sizeof ("Infinity") - 1);
75     
76   if (value == NEGATIVE_INFINITY)
77     return JvNewStringLatin1 ("-Infinity", sizeof ("-Infinity") - 1);
78     
79   char buffer[50], result[50];
80   int decpt, sign;
81
82   _dtoa (value, 0, 20, &decpt, &sign, NULL, buffer, (int)isFloat);
83
84   value = fabs (value);
85
86   char *s = buffer;
87   char *d = result;
88
89   if (sign)
90     *d++ = '-';
91
92   if (value >= 1e-3 && value < 1e7 || value == 0)
93     {
94       if (decpt <= 0)
95         *d++ = '0';
96       else
97         {
98           for (int i = 0; i < decpt; i++)
99             if (*s)
100               *d++ = *s++;
101             else
102               *d++ = '0';
103         }
104
105       *d++ = '.';
106
107       if (*s == 0)
108         {
109           *d++ = '0';
110           decpt++;
111         }
112           
113       while (decpt++ < 0)
114         *d++ = '0';      
115       
116       while (*s)
117         *d++ = *s++;
118
119       *d = 0;
120
121       return JvNewStringLatin1 (result, strlen (result));
122     }
123
124   *d++ = *s++;
125   decpt--;
126   *d++ = '.';
127   
128   if (*s == 0)
129     *d++ = '0';
130
131   while (*s)
132     *d++ = *s++;
133
134   *d++ = 'E';
135   
136   if (decpt < 0)
137     {
138       *d++ = '-';
139       decpt = -decpt;
140     }
141
142   {
143     char exp[4];
144     char *e = exp + sizeof exp;
145     
146     *--e = 0;
147     do
148       {
149         *--e = '0' + decpt % 10;
150         decpt /= 10;
151       }
152     while (decpt > 0);
153
154     while (*e)
155       *d++ = *e++;
156   }
157   
158   *d = 0;
159
160   return JvNewStringLatin1 (result, strlen (result));
161 }
162
163 jdouble 
164 java::lang::Double::parseDouble(jstring str)
165 {
166   int length = str->length();
167   // Note that UTF can expand 3x.
168
169 #ifdef HAVE_ALLOCA
170   char *data = (char *) alloca (3 * length + 1);
171 #else
172 #error --- need an alternate implementation here ---
173 #endif
174
175   data[_Jv_GetStringUTFRegion (str, 0, length, data)] = 0; 
176
177   struct _Jv_reent reent;  
178   memset (&reent, 0, sizeof reent);
179
180   double val = _strtod_r (&reent, data, NULL);
181
182   if (reent._errno)
183     _Jv_Throw (new NumberFormatException);
184
185   return val;
186 }