OSDN Git Service

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