Merge from mainline
[official-gcc.git] / libjava / java / lang / natDouble.cc
blob1a33a57158edc39621581150accb40884f380550
1 // natDouble.cc - Implementation of java.lang.VMDouble native methods.
3 /* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005, 2006 Free Software Foundation
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
9 details. */
11 #include <config.h>
13 #include <stdlib.h>
15 #include <gcj/cni.h>
16 #include <java/lang/String.h>
17 #include <java/lang/Double.h>
18 #include <java/lang/VMDouble.h>
19 #include <java/lang/Character.h>
20 #include <java/lang/NumberFormatException.h>
21 #include <jvm.h>
23 #include <stdio.h>
24 #include <string.h>
26 #include "fdlibm.h"
28 union u
30 jlong l;
31 jdouble d;
34 jlong
35 java::lang::VMDouble::doubleToLongBits(jdouble value)
37 union u u;
38 u.d = value;
40 jlong e = u.l & 0x7ff0000000000000LL;
41 jlong f = u.l & 0x000fffffffffffffLL;
43 if (e == 0x7ff0000000000000LL && f != 0L)
44 u.l = 0x7ff8000000000000LL;
46 return u.l;
49 jlong
50 java::lang::VMDouble::doubleToRawLongBits(jdouble value)
52 union u u;
53 u.d = value;
54 return u.l;
57 jdouble
58 java::lang::VMDouble::longBitsToDouble(jlong bits)
60 union u u;
61 u.l = bits;
62 return u.d;
65 jstring
66 java::lang::VMDouble::toString(jdouble value, jboolean isFloat)
68 if (Double::isNaN (value))
69 return JvNewStringLatin1 ("NaN", sizeof ("NaN") - 1);
71 if (value == Double::POSITIVE_INFINITY)
72 return JvNewStringLatin1 ("Infinity", sizeof ("Infinity") - 1);
74 if (value == Double::NEGATIVE_INFINITY)
75 return JvNewStringLatin1 ("-Infinity", sizeof ("-Infinity") - 1);
77 char buffer[50], result[50];
78 int decpt, sign;
80 _dtoa (value, 0, 20, &decpt, &sign, NULL, buffer, (int)isFloat);
82 value = fabs (value);
84 char *s = buffer;
85 char *d = result;
87 if (sign)
88 *d++ = '-';
90 if (value >= 1e-3 && value < 1e7 || value == 0)
92 if (decpt <= 0)
93 *d++ = '0';
94 else
96 for (int i = 0; i < decpt; i++)
97 if (*s)
98 *d++ = *s++;
99 else
100 *d++ = '0';
103 *d++ = '.';
105 if (*s == 0)
107 *d++ = '0';
108 decpt++;
111 while (decpt++ < 0)
112 *d++ = '0';
114 while (*s)
115 *d++ = *s++;
117 *d = 0;
119 return JvNewStringLatin1 (result, strlen (result));
122 *d++ = *s++;
123 decpt--;
124 *d++ = '.';
126 if (*s == 0)
127 *d++ = '0';
129 while (*s)
130 *d++ = *s++;
132 *d++ = 'E';
134 if (decpt < 0)
136 *d++ = '-';
137 decpt = -decpt;
141 char exp[4];
142 char *e = exp + sizeof exp;
144 *--e = 0;
147 *--e = '0' + decpt % 10;
148 decpt /= 10;
150 while (decpt > 0);
152 while (*e)
153 *d++ = *e++;
156 *d = 0;
158 return JvNewStringLatin1 (result, strlen (result));
161 jdouble
162 java::lang::VMDouble::parseDouble(jstring str)
164 int length = str->length();
166 while (length > 0
167 && Character::isWhitespace(str->charAt(length - 1)))
168 length--;
170 // The String could end with a f/F/d/D which is valid but we don't need.
171 bool saw_trailer = false;
172 if (length > 0)
174 jchar last = str->charAt(length-1);
175 if (last == 'f' || last == 'F' || last == 'd' || last == 'D')
177 length--;
178 saw_trailer = true;
182 jsize start = 0;
183 while (length > 0
184 && Character::isWhitespace(str->charAt(start)))
185 start++, length--;
187 if (length > 0)
189 // Note that UTF can expand 3x.
190 char *data = (char *) __builtin_alloca (3 * length + 1);
191 jsize blength = _Jv_GetStringUTFRegion (str, start, length, data);
192 data[blength] = 0;
194 if (! saw_trailer)
196 if (! strcmp (data, "NaN") || ! strcmp (data, "+NaN")
197 || ! strcmp (data, "-NaN"))
198 return Double::NaN;
199 else if (! strcmp (data, "Infinity") || ! strcmp (data, "+Infinity"))
200 return Double::POSITIVE_INFINITY;
201 else if (! strcmp (data, "-Infinity"))
202 return Double::NEGATIVE_INFINITY;
205 struct _Jv_reent reent;
206 memset (&reent, 0, sizeof reent);
208 char *endptr;
209 double val = _strtod_r (&reent, data, &endptr);
210 if (endptr == data + blength)
211 return val;
213 throw new NumberFormatException(str);