diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/java/lang/natVMDouble.cc | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libjava/java/lang/natVMDouble.cc')
-rw-r--r-- | libjava/java/lang/natVMDouble.cc | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/libjava/java/lang/natVMDouble.cc b/libjava/java/lang/natVMDouble.cc new file mode 100644 index 000000000..f770bc422 --- /dev/null +++ b/libjava/java/lang/natVMDouble.cc @@ -0,0 +1,215 @@ +// 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); +} |