Показать сообщение отдельно
Старый 11.02.2017, 23:39   #71  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
721 / 535 (19) +++++++
Регистрация: 14.10.2004
Как и предвидел Маззи, вычисление первых 10 тысяч элементов ряда фибоначчи должно занимать в Аксапте меньше одной минуты. У меня получился результат 18 секунд без вывода в окно инфолога, и 57 секунд - с выводом результата в инфолог (еще секунд 15 сам инфолог перерисовывается - я это в расчет не беру). Для 40 тысяч элементов джоб выполняется 2 с половиной минуты без вывода в инфолог.

Если закомментировать строку кода "info(total2str());", то получится результат без вывода в инфолог, который работает 18 секунд.

Данный джоб может без переполнения вычислить порядка 1000*18*5 = 90000 чисел Фибоначчи. Если надо вычислить большее количество, то надо переопределить макрос #define.maxSize(1000).

В качестве хранения одного числа используется массив из 1000 чисел int64. В одном элементе массива хранится число длиной до 18 знаков.В среднем, после каждого 5-го числа разряд увеличивается на 1. Поэтому и такая формула для лимита 1000*18*5 = 90000

X++:
static void Job120(Args _args)
{
    int fibonacciSize = 10000;
    #define.maxSize(1000)
    int64 x[#maxSize];
    int   xSize = 1;
    int64 y[#maxSize];
    int   ySize = 1;
    int64 total[#maxSize];
    int   totalSize = 1;
    int64 over;
    int64 maxInt64 = 1000000000000000000; //значение int64, удвоение которого не приведет к переполнению
    #define.int64x0(18) //столько нулей в значении int64, удвоение которого не приведет к переполнению
    SysOperationProgress    p = new SysOperationProgress();
    int   c;

    //суммирует массивы x и y, записывает результат в массив total
    void sumInt64Array()
    {
        int64 result;
        int64 digit;
        int j;
        int64 a;
        int64 b;
        int n;
        ;
        totalSize = 1;
        for (j = max(xSize, ySize); j >= 1; j--)
        {
            n ++;
            if (xSize >= n)
                a = x[n];
            else
                a = 0;
            if (ySize >= n)
                b = y[n];
            else
                b = 0;

            result = digit + a + b;
            over = result - maxInt64;
            digit = 0;
            if (over > 0)
            {
                result -= maxInt64;
                while(over > 0)
                {
                    digit ++;
                    over -= maxInt64;
                }
            }

            total[n] = result;
        }
        totalSize = n;
        if (digit)
        {
            totalSize ++;
            total[totalSize] = digit;
        }
    }

    str total2str()
    {
        int i;
        str ret;
        str s;
        int len;
        ;
        for (i = totalSize; i >= 1; i--)
        {
            s = strfmt("%1", total[i]);
            if (i < totalSize)
            {
                len = strLen(s);
                if (len < #int64x0)
                    s = strFmt("%1%2", strRep("0", #int64x0 - len), s);
            }
            ret += s;
            //ret = strFmt("%1%2", ret, s);
        }
        return ret;
    }
    ;
    p.settotal(fibonacciSize);
    p.update(true);
    x[1] = 0;
    y[1] = 1;
    info(strfmt("1: %1", x[1]));
    info(strfmt("2: %1", y[1]));
    c = 2;
    fibonacciSize -= 2;
    while (fibonacciSize > 0)
    {
        p.incCount();
        p.update(true);
        fibonacciSize --;
        sumInt64Array();
        c ++;
        info(strFmt("%1: %2", c, total2str()));
        [x, y] = [y, total];
        [xSize, ySize] = [ySize, totalSize];
    }
}

Последний раз редактировалось Ace of Database; 12.02.2017 в 01:35.
За это сообщение автора поблагодарили: mazzy (10), Lemming (5).