OSDN Git Service

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