// natDouble.cc - Implementation of java.lang.Double native methods. /* Copyright (C) 1998, 1999 Cygnus Solutions 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 /* AIX requires this to be the first thing in the file. */ #ifndef __GNUC__ # if HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ char *alloca (); # endif # endif # endif #endif #include #include #include #include #include #include #include #include #include "mprec.h" union u { jlong l; jdouble d; }; jlong java::lang::Double::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; } jdouble java::lang::Double::longBitsToDouble(jlong bits) { union u u; u.l = bits; return u.d; } jstring java::lang::Double::toString(jdouble value, jboolean isFloat) { if (isNaN (value)) return JvNewStringLatin1 ("NaN", sizeof ("NaN") - 1); if (value == POSITIVE_INFINITY) return JvNewStringLatin1 ("Infinity", sizeof ("Infinity") - 1); if (value == 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::Double::doubleValueOf(jstring str) { int length = str->length(); // Note that UTF can expand 3x. #ifdef HAVE_ALLOCA char *data = (char *) alloca (3 * length + 1); #else #error --- need an alternate implementation here --- #endif data[_Jv_GetStringUTFRegion (str, 0, length, data)] = 0; struct _Jv_reent reent; memset (&reent, 0, sizeof reent); double val = _strtod_r (&reent, data, NULL); if (reent._errno) _Jv_Throw (new NumberFormatException); return val; }