Fixed 54/53 bit bug in random()

Added start of runtimestrings...
This commit is contained in:
rogerl%netscape.com 2003-07-09 22:56:56 +00:00
Родитель 8e19c00ea2
Коммит f28d1108b2
2 изменённых файлов: 104 добавлений и 5 удалений

Просмотреть файл

@ -218,8 +218,8 @@ static void random_init(JS2Metadata *meta)
meta->rngInitialized = true;
/* meta->rngMultiplier = 0x5DEECE66DL */
JSLL_ISHL(tmp, 0x5D, 32);
JSLL_UI2L(tmp2, 0xEECE66DL);
JSLL_ISHL(tmp, 0x5, 32);
JSLL_UI2L(tmp2, 0xDEECE66DL);
JSLL_OR(meta->rngMultiplier, tmp, tmp2);
/* meta->rngAddend = 0xBL */
@ -230,8 +230,8 @@ static void random_init(JS2Metadata *meta)
JSLL_SHL(tmp2, tmp, 48);
JSLL_SUB(meta->rngMask, tmp2, tmp);
/* meta->rngDscale = (jsdouble)(1L << 54) */
JSLL_SHL(tmp2, tmp, 54);
/* meta->rngDscale = (jsdouble)(1L << 53) */
JSLL_SHL(tmp2, tmp, 53);
JSLL_L2D(meta->rngDscale, tmp2);
/* Finally, set the seed from current time. */
@ -257,7 +257,7 @@ static float64 random_nextDouble(JS2Metadata *meta)
int64 tmp, tmp2;
float64 d;
JSLL_ISHL(tmp, random_next(meta, 27), 27);
JSLL_ISHL(tmp, random_next(meta, 26), 27);
JSLL_UI2L(tmp2, random_next(meta, 27));
JSLL_ADD(tmp, tmp, tmp2);
JSLL_L2D(d, tmp);

Просмотреть файл

@ -0,0 +1,99 @@
class JS2StringElement {
public:
JS2StringElement(uint16 length) : length(length), chars(new jschar[length]) { }
JS2StringElement(uint16 length, jschar *source) : length(length), chars(new jschar[length]) { for (uint16 i = 0; i < length; i++) chars[i] = source[i]; }
uint16 getLength() const { return length; }
jschar *getChars() const { return chars; }
void insert(uint16 index, uint16 length, jschar *text)
{
for (uint16 i = 0; i < length; i++, index++)
chars[index] = text[i];
}
private:
uint16 length;
jschar *chars;
};
class JS2String {
public:
JS2String(uint16 length, jschar *text) : count(1), contents[0] = new JS2StringElement(length, text) { }
JS2String(const JS2String &a, const JS2String &b)
{
count = a.getCount() + b.getCount();
if (count <= 4) {
uint16 i;
for (i = 0; i < a.getCount(); i++)
contents[i] = a.contents[i];
for (uint16 j = 0; j < b.getCount(); j++, i++)
contents[i] = b.contents[j];
}
else {
count = 1;
contents[0] = new JS2StringElement(a.getLength() + b.getLength());
uint16 i;
uint16 index = 0;
for (i = 0; i < a.getCount(); i++) {
contents[0]->insert(index, a.contents[i]->getLength(), a.contents[i]->getChars());
index += a.contents[i]->getLength();
}
for (i = 0; i < b.getCount(); i++) {
contents[0]->insert(index, b.contents[i]->getLength(), b.contents[i]->getChars());
index += b.contents[i]->getLength()
}
}
}
void add(const JS2String &a)
{
ASSERT((count + a.count) <= 4);
for (uint16 i = 0; i < a.count; i++, count++)
contents[count] = a.contents[i];
}
uint16 getCount() const { return count; }
uint16 getLength() const { uint16 t = 0; for (uint16 i = 0; i < count; i++) t += contents[i]->getLength(); return t; }
void collapse()
{
if (count > 1) {
JS2StringElement *t = new JS2StringElement(getLength());
for (uint16 i = 0; i < count; i++) {
t->insert(index, contents[i]->getLength(), contents[i]->getChars());
index += contents[i]->getLength();
}
count = 1;
contents[0] = t;
}
}
jschar *getChars() { collapse(); return contents[0]->getChars(); }
private:
uint16 count;
JS2StringElement *contents[4];
};
JS2String &operator +(const JS2String &a, const JS2String &b) { return JS2String(a, b); }
JS2String &operator +=(const JS2String &a, const JS2String &b)
{
if ((a.getCount() + b.getCount) <= 4) {
a.add(b);
return a;
}
else
return JS2String(a, b);
}