BinaryDigitReader logic is inlined in ScriptRuntime.stringToNumber removing the need in the class.

This commit is contained in:
igor%mir2.org 2003-10-09 17:38:34 +00:00
parent 4c00c9dd8c
commit fe83dbd84d
2 changed files with 81 additions and 101 deletions

View File

@ -1,75 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Waldemar Horwat
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the NPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the NPL or the GPL.
*/
package org.mozilla.javascript;
final class BinaryDigitReader {
int lgBase; // Logarithm of base of number
int digit; // Current digit value in radix given by base
int digitPos; // Bit position of last bit extracted from digit
String digits; // String containing the digits
int start; // Index of the first remaining digit
int end; // Index past the last remaining digit
BinaryDigitReader(int base, String digits, int start, int end) {
lgBase = 0;
while (base != 1) {
lgBase++;
base >>= 1;
}
digitPos = 0;
this.digits = digits;
this.start = start;
this.end = end;
}
/* Return the next binary digit from the number or -1 if done */
int getNextBinaryDigit()
{
if (digitPos == 0) {
if (start == end)
return -1;
char c = digits.charAt(start++);
if ('0' <= c && c <= '9')
digit = c - '0';
else if ('a' <= c && c <= 'z')
digit = c - 'a' + 10;
else digit = c - 'A' + 10;
digitPos = lgBase;
}
return digit >> --digitPos & 1;
}
}

View File

@ -227,38 +227,93 @@ public class ScriptRuntime {
* occurs when reading the number 0x1000000000000081, which
* rounds to 0x1000000000000000 instead of 0x1000000000000100.
*/
BinaryDigitReader bdr = new BinaryDigitReader(radix, s, start, end);
int bit;
sum = 0.0;
int bitShiftInChar = 1;
int digit = 0;
/* Skip leading zeros. */
do {
bit = bdr.getNextBinaryDigit();
} while (bit == 0);
final int SKIP_LEADING_ZEROS = 0;
final int FIRST_EXACT_53_BITS = 1;
final int AFTER_BIT_53 = 2;
final int ZEROS_AFTER_54 = 3;
final int MIXED_AFTER_54 = 4;
if (bit == 1) {
/* Gather the 53 significant bits (including the leading 1) */
int state = SKIP_LEADING_ZEROS;
int exactBitsLimit = 53;
double factor = 0.0;
boolean bit53 = false;
// bit54 is the 54th bit (the first dropped from the mantissa)
boolean bit54 = false;
for (;;) {
if (bitShiftInChar == 1) {
if (start == end)
break;
digit = s.charAt(start++);
if ('0' <= digit && digit <= '9')
digit -= '0';
else if ('a' <= digit && digit <= 'z')
digit -= 'a' - 10;
else
digit -= 'A' - 10;
bitShiftInChar = radix;
}
bitShiftInChar >>= 1;
boolean bit = (digit & bitShiftInChar) != 0;
switch (state) {
case SKIP_LEADING_ZEROS:
if (bit) {
--exactBitsLimit;
sum = 1.0;
for (int j = 52; j != 0; j--) {
bit = bdr.getNextBinaryDigit();
if (bit < 0)
return sum;
sum = sum*2 + bit;
state = FIRST_EXACT_53_BITS;
}
/* bit54 is the 54th bit (the first dropped from the mantissa) */
int bit54 = bdr.getNextBinaryDigit();
if (bit54 >= 0) {
double factor = 2.0;
int sticky = 0; /* sticky is 1 if any bit beyond the 54th is 1 */
int bit3;
while ((bit3 = bdr.getNextBinaryDigit()) >= 0) {
sticky |= bit3;
break;
case FIRST_EXACT_53_BITS:
sum *= 2.0;
if (bit)
sum += 1.0;
--exactBitsLimit;
if (exactBitsLimit == 0) {
bit53 = bit;
state = AFTER_BIT_53;
}
break;
case AFTER_BIT_53:
bit54 = bit;
factor = 2.0;
state = ZEROS_AFTER_54;
break;
case ZEROS_AFTER_54:
if (bit) {
state = MIXED_AFTER_54;
}
// fallthrough
case MIXED_AFTER_54:
factor *= 2;
break;
}
sum += bit54 & (bit | sticky);
}
switch (state) {
case SKIP_LEADING_ZEROS:
sum = 0.0;
break;
case FIRST_EXACT_53_BITS:
case AFTER_BIT_53:
// do nothing
break;
case ZEROS_AFTER_54:
// x1.1 -> x1 + 1 (round up)
// x0.1 -> x0 (round down)
if (bit54 & bit53)
sum += 1.0;
sum *= factor;
}
break;
case MIXED_AFTER_54:
// x.100...1.. -> x + 1 (round up)
// x.0anything -> x (round down)
if (bit54)
sum += 1.0;
sum *= factor;
break;
}
}
/* We don't worry about inaccurate numbers for any other base. */