123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- // natVMDouble.cc - Implementation of java.lang.VMDouble native methods.
- /* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005, 2006, 2007
- Free Software Foundation
- This file is part of libgcj.
- This software is copyrighted work licensed under the terms of the
- Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
- details. */
- #include <config.h>
- #include <stdlib.h>
- #include <gcj/cni.h>
- #include <java/lang/String.h>
- #include <java/lang/Double.h>
- #include <java/lang/VMDouble.h>
- #include <java/lang/Character.h>
- #include <java/lang/NumberFormatException.h>
- #include <jvm.h>
- #include <stdio.h>
- #include <string.h>
- #include "fdlibm.h"
- union u
- {
- jlong l;
- jdouble d;
- };
- jlong
- java::lang::VMDouble::doubleToLongBits(jdouble value)
- {
- union u u;
- u.d = value;
-
- jlong e = u.l & 0x7ff0000000000000LL;
- jlong f = u.l & 0x000fffffffffffffLL;
- if (e == 0x7ff0000000000000LL && f != 0L)
- u.l = 0x7ff8000000000000LL;
- return u.l;
- }
- jlong
- java::lang::VMDouble::doubleToRawLongBits(jdouble value)
- {
- union u u;
- u.d = value;
- return u.l;
- }
- jdouble
- java::lang::VMDouble::longBitsToDouble(jlong bits)
- {
- union u u;
- u.l = bits;
- return u.d;
- }
- jstring
- java::lang::VMDouble::toString(jdouble value, jboolean isFloat)
- {
- if (Double::isNaN (value))
- return JvNewStringLatin1 ("NaN", sizeof ("NaN") - 1);
-
- if (value == Double::POSITIVE_INFINITY)
- return JvNewStringLatin1 ("Infinity", sizeof ("Infinity") - 1);
-
- if (value == Double::NEGATIVE_INFINITY)
- return JvNewStringLatin1 ("-Infinity", sizeof ("-Infinity") - 1);
-
- char buffer[50], result[50];
- int decpt, sign;
- _dtoa (value, 0, 20, &decpt, &sign, NULL, buffer, (int)isFloat);
- value = fabs (value);
- char *s = buffer;
- char *d = result;
- if (sign)
- *d++ = '-';
- if ((value >= 1e-3 && value < 1e7) || value == 0)
- {
- if (decpt <= 0)
- *d++ = '0';
- else
- {
- for (int i = 0; i < decpt; i++)
- if (*s)
- *d++ = *s++;
- else
- *d++ = '0';
- }
- *d++ = '.';
- if (*s == 0)
- {
- *d++ = '0';
- decpt++;
- }
-
- while (decpt++ < 0)
- *d++ = '0';
-
- while (*s)
- *d++ = *s++;
- *d = 0;
- return JvNewStringLatin1 (result, strlen (result));
- }
- *d++ = *s++;
- decpt--;
- *d++ = '.';
-
- if (*s == 0)
- *d++ = '0';
- while (*s)
- *d++ = *s++;
- *d++ = 'E';
-
- if (decpt < 0)
- {
- *d++ = '-';
- decpt = -decpt;
- }
- {
- char exp[4];
- char *e = exp + sizeof exp;
-
- *--e = 0;
- do
- {
- *--e = '0' + decpt % 10;
- decpt /= 10;
- }
- while (decpt > 0);
- while (*e)
- *d++ = *e++;
- }
-
- *d = 0;
- return JvNewStringLatin1 (result, strlen (result));
- }
- jdouble
- java::lang::VMDouble::parseDouble(jstring str)
- {
- int length = str->length();
- while (length > 0
- && Character::isWhitespace(str->charAt(length - 1)))
- length--;
- // The String could end with a f/F/d/D which is valid but we don't need.
- bool saw_trailer = false;
- if (length > 0)
- {
- jchar last = str->charAt(length-1);
- if (last == 'f' || last == 'F' || last == 'd' || last == 'D')
- {
- length--;
- saw_trailer = true;
- }
- }
- jsize start = 0;
- while (length > 0
- && Character::isWhitespace(str->charAt(start)))
- start++, length--;
- if (length > 0)
- {
- // Note that UTF can expand 3x.
- char *data = (char *) __builtin_alloca (3 * length + 1);
- jsize blength = _Jv_GetStringUTFRegion (str, start, length, data);
- data[blength] = 0;
- if (! saw_trailer)
- {
- if (! strcmp (data, "NaN") || ! strcmp (data, "+NaN")
- || ! strcmp (data, "-NaN"))
- return Double::NaN;
- else if (! strcmp (data, "Infinity") || ! strcmp (data, "+Infinity"))
- return Double::POSITIVE_INFINITY;
- else if (! strcmp (data, "-Infinity"))
- return Double::NEGATIVE_INFINITY;
- }
- struct _Jv_reent reent;
- memset (&reent, 0, sizeof reent);
- char *endptr;
- double val = _strtod_r (&reent, data, &endptr);
- if (endptr == data + blength)
- return val;
- }
- throw new NumberFormatException(str);
- }
|