Показать сообщение отдельно
Старый 01.03.2016, 06:00
caseyryan вне форума Посмотреть профиль Отправить личное сообщение для caseyryan Найти все сообщения от caseyryan
  № 18  
Ответить с цитированием
caseyryan
 
Аватар для caseyryan

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
Цитата:
Сообщение от 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 тут ни при чем.
__________________
Ко мне можно и нужно обращаться на ты)