OSDN Git Service

Initial revision
[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   return u.l;
51 }
52
53 jdouble 
54 java::lang::Double::longBitsToDouble(jlong bits)
55 {
56   union u u;
57   u.l = bits;
58   return u.d;
59 }
60
61 jstring 
62 java::lang::Double::toString(jdouble value, jboolean isFloat)
63 {
64   if (isNaN (value))
65     return JvNewStringLatin1 ("NaN", sizeof ("NaN") - 1);
66     
67   if (value == POSITIVE_INFINITY)
68     return JvNewStringLatin1 ("Infinity", sizeof ("Infinity") - 1);
69     
70   if (value == NEGATIVE_INFINITY)
71     return JvNewStringLatin1 ("-Infinity", sizeof ("-Infinity") - 1);
72     
73   char buffer[50], result[50];
74   int decpt, sign;
75
76   _dtoa (value, 0, 20, &decpt, &sign, NULL, buffer, (int)isFloat);
77
78   value = fabs (value);
79
80   char *s = buffer;
81   char *d = result;
82
83   if (sign)
84     *d++ = '-';
85
86   if (value >= 1e-3 && value < 1e7 || value == 0)
87     {
88       if (decpt <= 0)
89         *d++ = '0';
90       else
91         {
92           for (int i = 0; i < decpt; i++)
93             if (*s)
94               *d++ = *s++;
95             else
96               *d++ = '0';
97         }
98
99       *d++ = '.';
100
101       if (*s == 0)
102         {
103           *d++ = '0';
104           decpt++;
105         }
106           
107       while (decpt++ < 0)
108         *d++ = '0';      
109       
110       while (*s)
111         *d++ = *s++;
112
113       *d = 0;
114
115       return JvNewStringLatin1 (result, strlen (result));
116     }
117
118   *d++ = *s++;
119   decpt--;
120   *d++ = '.';
121   
122   if (*s == 0)
123     *d++ = '0';
124
125   while (*s)
126     *d++ = *s++;
127
128   *d++ = 'E';
129   
130   if (decpt < 0)
131     {
132       *d++ = '-';
133       decpt = -decpt;
134     }
135
136   {
137     char exp[4];
138     char *e = exp + sizeof exp;
139     
140     *--e = 0;
141     do
142       {
143         *--e = '0' + decpt % 10;
144         decpt /= 10;
145       }
146     while (decpt > 0);
147
148     while (*e)
149       *d++ = *e++;
150   }
151   
152   *d = 0;
153
154   return JvNewStringLatin1 (result, strlen (result));
155 }
156
157 jdouble 
158 java::lang::Double::doubleValueOf(jstring str)
159 {
160   int length = str->length();
161   // Note that UTF can expand 3x.
162
163 #ifdef HAVE_ALLOCA
164   char *data = (char *) alloca (3 * length + 1);
165 #else
166 #error --- need an alternate implementation here ---
167 #endif
168
169   data[_Jv_GetStringUTFRegion (str, 0, length, data)] = 0; 
170
171   struct _Jv_reent reent;  
172   memset (&reent, 0, sizeof reent);
173
174   double val = _strtod_r (&reent, data, NULL);
175
176   if (reent._errno)
177     _Jv_Throw (new NumberFormatException);
178
179   return val;
180 }