| 1 | // natDouble.cc - Implementation of java.lang.Double native methods.
|
|---|
| 2 |
|
|---|
| 3 | /* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation
|
|---|
| 4 |
|
|---|
| 5 | This file is part of libgcj.
|
|---|
| 6 |
|
|---|
| 7 | This software is copyrighted work licensed under the terms of the
|
|---|
| 8 | Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
|
|---|
| 9 | details. */
|
|---|
| 10 |
|
|---|
| 11 | #include <config.h>
|
|---|
| 12 |
|
|---|
| 13 | #include <stdlib.h>
|
|---|
| 14 |
|
|---|
| 15 | #include <gcj/cni.h>
|
|---|
| 16 | #include <java/lang/String.h>
|
|---|
| 17 | #include <java/lang/Double.h>
|
|---|
| 18 | #include <java/lang/Character.h>
|
|---|
| 19 | #include <java/lang/NumberFormatException.h>
|
|---|
| 20 | #include <jvm.h>
|
|---|
| 21 |
|
|---|
| 22 | #include <stdio.h>
|
|---|
| 23 | #include <string.h>
|
|---|
| 24 |
|
|---|
| 25 | #include "fdlibm.h"
|
|---|
| 26 |
|
|---|
| 27 | union u
|
|---|
| 28 | {
|
|---|
| 29 | jlong l;
|
|---|
| 30 | jdouble d;
|
|---|
| 31 | };
|
|---|
| 32 |
|
|---|
| 33 | jlong
|
|---|
| 34 | java::lang::Double::doubleToLongBits(jdouble value)
|
|---|
| 35 | {
|
|---|
| 36 | union u u;
|
|---|
| 37 | u.d = value;
|
|---|
| 38 |
|
|---|
| 39 | jlong e = u.l & 0x7ff0000000000000LL;
|
|---|
| 40 | jlong f = u.l & 0x000fffffffffffffLL;
|
|---|
| 41 |
|
|---|
| 42 | if (e == 0x7ff0000000000000LL && f != 0L)
|
|---|
| 43 | u.l = 0x7ff8000000000000LL;
|
|---|
| 44 |
|
|---|
| 45 | return u.l;
|
|---|
| 46 | }
|
|---|
| 47 |
|
|---|
| 48 | jlong
|
|---|
| 49 | java::lang::Double::doubleToRawLongBits(jdouble value)
|
|---|
| 50 | {
|
|---|
| 51 | union u u;
|
|---|
| 52 | u.d = value;
|
|---|
| 53 | return u.l;
|
|---|
| 54 | }
|
|---|
| 55 |
|
|---|
| 56 | jdouble
|
|---|
| 57 | java::lang::Double::longBitsToDouble(jlong bits)
|
|---|
| 58 | {
|
|---|
| 59 | union u u;
|
|---|
| 60 | u.l = bits;
|
|---|
| 61 | return u.d;
|
|---|
| 62 | }
|
|---|
| 63 |
|
|---|
| 64 | jstring
|
|---|
| 65 | java::lang::Double::toString(jdouble value, jboolean isFloat)
|
|---|
| 66 | {
|
|---|
| 67 | if (isNaN (value))
|
|---|
| 68 | return JvNewStringLatin1 ("NaN", sizeof ("NaN") - 1);
|
|---|
| 69 |
|
|---|
| 70 | if (value == POSITIVE_INFINITY)
|
|---|
| 71 | return JvNewStringLatin1 ("Infinity", sizeof ("Infinity") - 1);
|
|---|
| 72 |
|
|---|
| 73 | if (value == NEGATIVE_INFINITY)
|
|---|
| 74 | return JvNewStringLatin1 ("-Infinity", sizeof ("-Infinity") - 1);
|
|---|
| 75 |
|
|---|
| 76 | char buffer[50], result[50];
|
|---|
| 77 | int decpt, sign;
|
|---|
| 78 |
|
|---|
| 79 | _dtoa (value, 0, 20, &decpt, &sign, NULL, buffer, (int)isFloat);
|
|---|
| 80 |
|
|---|
| 81 | value = fabs (value);
|
|---|
| 82 |
|
|---|
| 83 | char *s = buffer;
|
|---|
| 84 | char *d = result;
|
|---|
| 85 |
|
|---|
| 86 | if (sign)
|
|---|
| 87 | *d++ = '-';
|
|---|
| 88 |
|
|---|
| 89 | if (value >= 1e-3 && value < 1e7 || value == 0)
|
|---|
| 90 | {
|
|---|
| 91 | if (decpt <= 0)
|
|---|
| 92 | *d++ = '0';
|
|---|
| 93 | else
|
|---|
| 94 | {
|
|---|
| 95 | for (int i = 0; i < decpt; i++)
|
|---|
| 96 | if (*s)
|
|---|
| 97 | *d++ = *s++;
|
|---|
| 98 | else
|
|---|
| 99 | *d++ = '0';
|
|---|
| 100 | }
|
|---|
| 101 |
|
|---|
| 102 | *d++ = '.';
|
|---|
| 103 |
|
|---|
| 104 | if (*s == 0)
|
|---|
| 105 | {
|
|---|
| 106 | *d++ = '0';
|
|---|
| 107 | decpt++;
|
|---|
| 108 | }
|
|---|
| 109 |
|
|---|
| 110 | while (decpt++ < 0)
|
|---|
| 111 | *d++ = '0';
|
|---|
| 112 |
|
|---|
| 113 | while (*s)
|
|---|
| 114 | *d++ = *s++;
|
|---|
| 115 |
|
|---|
| 116 | *d = 0;
|
|---|
| 117 |
|
|---|
| 118 | return JvNewStringLatin1 (result, strlen (result));
|
|---|
| 119 | }
|
|---|
| 120 |
|
|---|
| 121 | *d++ = *s++;
|
|---|
| 122 | decpt--;
|
|---|
| 123 | *d++ = '.';
|
|---|
| 124 |
|
|---|
| 125 | if (*s == 0)
|
|---|
| 126 | *d++ = '0';
|
|---|
| 127 |
|
|---|
| 128 | while (*s)
|
|---|
| 129 | *d++ = *s++;
|
|---|
| 130 |
|
|---|
| 131 | *d++ = 'E';
|
|---|
| 132 |
|
|---|
| 133 | if (decpt < 0)
|
|---|
| 134 | {
|
|---|
| 135 | *d++ = '-';
|
|---|
| 136 | decpt = -decpt;
|
|---|
| 137 | }
|
|---|
| 138 |
|
|---|
| 139 | {
|
|---|
| 140 | char exp[4];
|
|---|
| 141 | char *e = exp + sizeof exp;
|
|---|
| 142 |
|
|---|
| 143 | *--e = 0;
|
|---|
| 144 | do
|
|---|
| 145 | {
|
|---|
| 146 | *--e = '0' + decpt % 10;
|
|---|
| 147 | decpt /= 10;
|
|---|
| 148 | }
|
|---|
| 149 | while (decpt > 0);
|
|---|
| 150 |
|
|---|
| 151 | while (*e)
|
|---|
| 152 | *d++ = *e++;
|
|---|
| 153 | }
|
|---|
| 154 |
|
|---|
| 155 | *d = 0;
|
|---|
| 156 |
|
|---|
| 157 | return JvNewStringLatin1 (result, strlen (result));
|
|---|
| 158 | }
|
|---|
| 159 |
|
|---|
| 160 | jdouble
|
|---|
| 161 | java::lang::Double::parseDouble(jstring str)
|
|---|
| 162 | {
|
|---|
| 163 | int length = str->length();
|
|---|
| 164 |
|
|---|
| 165 | while (length > 0
|
|---|
| 166 | && Character::isWhitespace(str->charAt(length - 1)))
|
|---|
| 167 | length--;
|
|---|
| 168 |
|
|---|
| 169 | // The String could end with a f/F/d/D which is valid but we don't need.
|
|---|
| 170 | if (length > 0)
|
|---|
| 171 | {
|
|---|
| 172 | jchar last = str->charAt(length-1);
|
|---|
| 173 | if (last == 'f' || last == 'F' || last == 'd' || last == 'D')
|
|---|
| 174 | length--;
|
|---|
| 175 | }
|
|---|
| 176 |
|
|---|
| 177 | jsize start = 0;
|
|---|
| 178 | while (length > 0
|
|---|
| 179 | && Character::isWhitespace(str->charAt(start)))
|
|---|
| 180 | start++, length--;
|
|---|
| 181 |
|
|---|
| 182 | if (length > 0)
|
|---|
| 183 | {
|
|---|
| 184 | // Note that UTF can expand 3x.
|
|---|
| 185 | char *data = (char *) __builtin_alloca (3 * length + 1);
|
|---|
| 186 | jsize blength = _Jv_GetStringUTFRegion (str, start, length, data);
|
|---|
| 187 | data[blength] = 0;
|
|---|
| 188 |
|
|---|
| 189 | struct _Jv_reent reent;
|
|---|
| 190 | memset (&reent, 0, sizeof reent);
|
|---|
| 191 |
|
|---|
| 192 | char *endptr;
|
|---|
| 193 | double val = _strtod_r (&reent, data, &endptr);
|
|---|
| 194 | if (endptr == data + blength)
|
|---|
| 195 | return val;
|
|---|
| 196 | }
|
|---|
| 197 | throw new NumberFormatException(str);
|
|---|
| 198 | }
|
|---|
| 199 |
|
|---|
| 200 | void
|
|---|
| 201 | java::lang::Double::initIDs()
|
|---|
| 202 | {
|
|---|
| 203 | // Not used in libgcj
|
|---|
| 204 | }
|
|---|