2008-10-16 Joseph Myers <joseph@codesourcery.com>
[official-gcc.git] / libjava / java / lang / natVMDouble.cc
blobf770bc422f8188a1f2cbd7609e64cce04630395c
1 // natVMDouble.cc - Implementation of java.lang.VMDouble native methods.
3 /* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005, 2006, 2007
4 Free Software Foundation
6 This file is part of libgcj.
8 This software is copyrighted work licensed under the terms of the
9 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
10 details. */
12 #include <config.h>
14 #include <stdlib.h>
16 #include <gcj/cni.h>
17 #include <java/lang/String.h>
18 #include <java/lang/Double.h>
19 #include <java/lang/VMDouble.h>
20 #include <java/lang/Character.h>
21 #include <java/lang/NumberFormatException.h>
22 #include <jvm.h>
24 #include <stdio.h>
25 #include <string.h>
27 #include "fdlibm.h"
29 union u
31 jlong l;
32 jdouble d;
35 jlong
36 java::lang::VMDouble::doubleToLongBits(jdouble value)
38 union u u;
39 u.d = value;
41 jlong e = u.l & 0x7ff0000000000000LL;
42 jlong f = u.l & 0x000fffffffffffffLL;
44 if (e == 0x7ff0000000000000LL && f != 0L)
45 u.l = 0x7ff8000000000000LL;
47 return u.l;
50 jlong
51 java::lang::VMDouble::doubleToRawLongBits(jdouble value)
53 union u u;
54 u.d = value;
55 return u.l;
58 jdouble
59 java::lang::VMDouble::longBitsToDouble(jlong bits)
61 union u u;
62 u.l = bits;
63 return u.d;
66 jstring
67 java::lang::VMDouble::toString(jdouble value, jboolean isFloat)
69 if (Double::isNaN (value))
70 return JvNewStringLatin1 ("NaN", sizeof ("NaN") - 1);
72 if (value == Double::POSITIVE_INFINITY)
73 return JvNewStringLatin1 ("Infinity", sizeof ("Infinity") - 1);
75 if (value == Double::NEGATIVE_INFINITY)
76 return JvNewStringLatin1 ("-Infinity", sizeof ("-Infinity") - 1);
78 char buffer[50], result[50];
79 int decpt, sign;
81 _dtoa (value, 0, 20, &decpt, &sign, NULL, buffer, (int)isFloat);
83 value = fabs (value);
85 char *s = buffer;
86 char *d = result;
88 if (sign)
89 *d++ = '-';
91 if ((value >= 1e-3 && value < 1e7) || value == 0)
93 if (decpt <= 0)
94 *d++ = '0';
95 else
97 for (int i = 0; i < decpt; i++)
98 if (*s)
99 *d++ = *s++;
100 else
101 *d++ = '0';
104 *d++ = '.';
106 if (*s == 0)
108 *d++ = '0';
109 decpt++;
112 while (decpt++ < 0)
113 *d++ = '0';
115 while (*s)
116 *d++ = *s++;
118 *d = 0;
120 return JvNewStringLatin1 (result, strlen (result));
123 *d++ = *s++;
124 decpt--;
125 *d++ = '.';
127 if (*s == 0)
128 *d++ = '0';
130 while (*s)
131 *d++ = *s++;
133 *d++ = 'E';
135 if (decpt < 0)
137 *d++ = '-';
138 decpt = -decpt;
142 char exp[4];
143 char *e = exp + sizeof exp;
145 *--e = 0;
148 *--e = '0' + decpt % 10;
149 decpt /= 10;
151 while (decpt > 0);
153 while (*e)
154 *d++ = *e++;
157 *d = 0;
159 return JvNewStringLatin1 (result, strlen (result));
162 jdouble
163 java::lang::VMDouble::parseDouble(jstring str)
165 int length = str->length();
167 while (length > 0
168 && Character::isWhitespace(str->charAt(length - 1)))
169 length--;
171 // The String could end with a f/F/d/D which is valid but we don't need.
172 bool saw_trailer = false;
173 if (length > 0)
175 jchar last = str->charAt(length-1);
176 if (last == 'f' || last == 'F' || last == 'd' || last == 'D')
178 length--;
179 saw_trailer = true;
183 jsize start = 0;
184 while (length > 0
185 && Character::isWhitespace(str->charAt(start)))
186 start++, length--;
188 if (length > 0)
190 // Note that UTF can expand 3x.
191 char *data = (char *) __builtin_alloca (3 * length + 1);
192 jsize blength = _Jv_GetStringUTFRegion (str, start, length, data);
193 data[blength] = 0;
195 if (! saw_trailer)
197 if (! strcmp (data, "NaN") || ! strcmp (data, "+NaN")
198 || ! strcmp (data, "-NaN"))
199 return Double::NaN;
200 else if (! strcmp (data, "Infinity") || ! strcmp (data, "+Infinity"))
201 return Double::POSITIVE_INFINITY;
202 else if (! strcmp (data, "-Infinity"))
203 return Double::NEGATIVE_INFINITY;
206 struct _Jv_reent reent;
207 memset (&reent, 0, sizeof reent);
209 char *endptr;
210 double val = _strtod_r (&reent, data, &endptr);
211 if (endptr == data + blength)
212 return val;
214 throw new NumberFormatException(str);