mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 05:45:37 +00:00
BinaryDigitReader logic is inlined in ScriptRuntime.stringToNumber removing the need in the class.
This commit is contained in:
parent
4c00c9dd8c
commit
fe83dbd84d
@ -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;
|
||||
}
|
||||
}
|
@ -227,39 +227,94 @@ 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) */
|
||||
sum = 1.0;
|
||||
for (int j = 52; j != 0; j--) {
|
||||
bit = bdr.getNextBinaryDigit();
|
||||
if (bit < 0)
|
||||
return sum;
|
||||
sum = sum*2 + bit;
|
||||
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;
|
||||
}
|
||||
/* 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;
|
||||
bitShiftInChar >>= 1;
|
||||
boolean bit = (digit & bitShiftInChar) != 0;
|
||||
|
||||
while ((bit3 = bdr.getNextBinaryDigit()) >= 0) {
|
||||
sticky |= bit3;
|
||||
factor *= 2;
|
||||
switch (state) {
|
||||
case SKIP_LEADING_ZEROS:
|
||||
if (bit) {
|
||||
--exactBitsLimit;
|
||||
sum = 1.0;
|
||||
state = FIRST_EXACT_53_BITS;
|
||||
}
|
||||
sum += bit54 & (bit | sticky);
|
||||
sum *= factor;
|
||||
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;
|
||||
}
|
||||
}
|
||||
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. */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user