Цитата:
Сообщение от alatar
Исходный код Math доступен. На разных архитектурах, естественно будет работать немного по разному (касательно времени), но и скорость выполнения байткода (после JIT'a) будет меняться.
Есть и более зависимые вещи. Работа с временем, например. Для иллюстрации getTimer в iOS и Android зависит от системного времени, если перевести часы в системе, можно и отрицательное время словить.
|
Исходный код метода parseInt просто жесть. Не задумывался даже, что для этого в реале требуется так много кода

Код AS3:
double MathUtils::parseInt(Stringp inStr, int32_t radix /*=10*/, bool strict /*=false*/ )
{
bool negate;
bool gotDigits = false;
double result = 0;
StringIndexer s(inStr);
int32_t index = skipSpaces(s, 0); // leading and trailing whitespace is valid.
index = handleSign(s, index, negate);
if (isHexNumber(s, index) && (radix == 16 || radix == 0) ) {
index += 2;
if (radix == 0)
radix = 16;
} else if (radix == 0) {
// default radix is 10
radix = 10;
}
// Make sure radix is valid, and we have digits
if (radix >= 2 && radix <= 36 && index < s->length()) {
result = 0;
int32_t start = index;
// Read the digits, generate result
while (index < s->length()) {
int32_t v = parseIntDigit(s[index]);
if (v == -1 || v >= radix) {
break;
}
result = result * radix + v;
gotDigits = true;
index++;
}
index = skipSpaces(s, index); // leading and trailing whitespace is valid.
if (strict && index < s->length()) {
return MathUtils::kNaN;
}
if ( result >= 0x20000000000000LL && // i.e. if the result may need at least 54 bits of mantissa
(radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32) ) {
// CN: we're here because we may have incurred roundoff error with the above.
// Error will creep in once we need more than the available 53 bits
// of precision in the mantissa portion of a double. No way to deduce
// this from the result, so we have to recalculate it more slowly.
result = 0;
int32_t powOf2 = 1;
for(int32_t x = radix; (x != 1); x >>= 1)
powOf2++;
powOf2--; // each word contains one less than this # of bits.
index = start;
int32_t v=0;
int32_t end,next;
// skip leading zeros
for(end=index; end < s->length() && s[end] == '0'; end++)
;
if (end >= s->length())
return 0;
for (next=0; next*powOf2 <= 52; next++) { // read first 52 non-zero digits. Once charPosition*log2(radix) is > 53, we can have rounding issues
v = parseIntDigit(s[end++]);
if (v == -1 || v >= radix) {
v = 0;
break;
}
result = result * radix + v;
if (end >= s->length())
break;
}
if (next*powOf2 > 52) { // If number contains more than 53 bits of precision, may need to roundUp last digit processed.
bool roundUp = false;
int32_t bit53 = 0;
int32_t bit54 = 0;
double factor = 1;
switch(radix) {
case 32: // last word read contained digits 51,52,53,54,55
bit53 = v & (1 << 2);
bit54 = v & (1 << 1);
roundUp = (v & 1);
break;
case 16: // last word read contained digits 50,51,52,53
bit53 = v & (1 << 0);
v = parseIntDigit(s[end]);
if (v != -1 && v < radix) {
factor *= radix;
bit54 = v & (1 << 3);
roundUp = (v & 0x3) != 0; // check if any bit after bit54 is set
} else {
roundUp = bit53 != 0;
}
break;
case 8: // last work read contained digits 49,50,51, next word contains 52,53,54
v = parseIntDigit(s[end]);
if (v == -1 || v >= radix) {
v = 0;
}
factor *= radix;
bit53 = v & (1 << 1);
bit54 = v & (1 << 0);
break;
case 4: // 51,52 - 53,54
v = parseIntDigit(s[end]);
if (v == -1 || v >= radix) {
v = 0;
}
factor *= radix;
bit53 = v & (1 << 1);
bit54 = v & (1 << 0);
break;
case 2: // 52 - 53 - 54
/*
v = parseIntDigit(s[end++]);
result = result * radix; // add factor before round-off adjustment for 52 bit
*/
bit53 = v & (1 << 0);
v = parseIntDigit(s[end]);
if (v != -1 && v < radix) {
factor *= radix;
bit54 = (v != -1 ? (v & (1 << 0)) : 0); // Might be there are only 53 digits.
}
break;
}
bit53 = !!bit53;
bit54 = !!bit54;
while(++end < s->length()) {
v = parseIntDigit(s[end]);
if (v == -1 || v >= radix) {
break;
}
roundUp |= (v != 0); // any trailing positive bit causes us to round up
factor *= radix;
}
roundUp = bit54 && (bit53 || roundUp);
result += (roundUp ? 1.0 : 0.0);
result *= factor;
}
}
/*
else if (radix == 10 && result >= 0x20000000000000)
// if there are more than 15 digits, roundoff error may affect us. Need to use exact integer rep instead of float
//int32_t numDigits = len - (s - sStart);
*/
if (negate) {
result = -result;
}
}
return gotDigits ? result : MathUtils::kNaN;
}
Что-то не нашел как вычисляются синусы и косинусы...
Цитата:
|
caseyryan, небольшой примечание: быстрей всего while. ASC2 при компиляции заменяет все for на while
|
Тогда еще небольшое примечание: так было всегда, ASC 2 тут ни при чем.