OSDN Git Service

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