1. C++ / Говнокод #11288

    −47

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    void init_by_array64(unsigned long long init_key[],
    		     unsigned long long key_length)
    {
        unsigned long long i, j, k;
        init_genrand64(19650218ULL);
        i=1; j=0;
        k = (NN>key_length ? NN : key_length);
        for (; k; k--) {
            mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 62)) * 3935559000370003845ULL))
              + init_key[j] + j; /* non linear */
            i++; j++;
            if (i>=NN) { mt[0] = mt[NN-1]; i=1; }
            if (j>=key_length) j=0;
        }
        for (k=NN-1; k; k--) {
            mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 62)) * 2862933555777941757ULL))
              - i; /* non linear */
            i++;
            if (i>=NN) { mt[0] = mt[NN-1]; i=1; }
        }
    
        mt[0] = 1ULL << 63; /* MSB is 1; assuring non-zero initial array */ 
    }

    "Чистый и ясный код" (с)

    Запостил: Fai, 24 Июня 2012

    Комментарии (21) RSS

    • К слову это из довольно большой программы, остальной код хороший. Эта функция видимо была выдрана из инета или другой программы, но оставлена как есть.
      Ответить
    • 3935559000370003845ULL
      Магические числа такие магические.
      Ответить
      • А то. Помню, читал где-то про разные алгоритмы хеширования. И там был комментарий вроде: "Автор алгоритма выбрал константу N. Никто так толком не смог объяснить почему, но это число, судя по всему, даёт лучшие результаты" :)
        Ответить
    • Это Вихрь Мерсена что-ли?

      UPD: Да. Он самый.

      http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt64.html

      UPD2: Ну нормальный код, оптимизированный на скорость, а не на понятность...
      Ответить
      • 1. Сделай чисто.
        2. Сделай ясно.
        3. Сделай понятно.
        4-1000. Дорабатывай и расширяй.
        1001. Прогони по профилировщику.
        1002. Ускоряй слабые места.

        К слову говно не только в том что структура слабовата, но и в выборе имён переменных: mt, NN, i, j, k.

        Или скорость работы уже от размера имён переменных зависит?
        Ответить
        • Выбор переменных да, говно. Но кстати непонятных мест в этом коде нет. Имхо если почитать алгоритм MT - все встанет на свои места.
          Ответить
          • В большом количестве кода вообще нет непонятных мест, но вот понятных и простых моментов я в этом коде не вижу.
            Ответить
            • А что здесь сложного кроме формул, которые, естественно, нельзя понять не изучая алгоритма MT? Структура кода же предельно проста и понятна:

              Цикл до max(длина_ключа, длина_вектора_состояния), смешивающий ключ с вектором состояния. i - позиция в векторе состояния, j - позиция в ключе. Обе переменных сбрасываются при переполнениях.

              Затем еще один пробег по всем элементам, который начинается с того места, на котором остановились в предыдущем цикле.

              Если этот код переписать с говорящими именами - ничего не изменится - т.к. ход работы виден и без них, а суть формул и констант они все равно не раскроют.
              Ответить
              • Ладно, закончим холивар, я увидел код, мне он не понравился, выложил. Может он и качественный.
                Ответить
          • Надо было функцию назвать apply_mt64. Если читающий не вкурил -- пошёл погуглил, что такое mt64.
            Ответить
            • А это не apply, это именно init_by_array :)

              Плохо поступил тот, кто спер пару функций из либы, и оставил их без контекста и без комментария о том что это и откуда оно взято. Вполне можно было поместить исходники либы (там ашка да сяшка) в ее оригинальном виде в каталог типа 3rdparty/mt64.
              Ответить
              • Вот комментарии автора. То что это вихрь Мерсенна не написано.

                //* initialize by an array with array-length */
                //* init_key is the array for initializing keys */
                //* key_length is its length */
                void init_by_array64(unsigned long long init_key[],
                	unsigned long long key_length)
                Ответить
                • Ну коммент скопипизжен им дословно. Нехороший человек этот автор, не уважает авторское право ;)
                  Ответить
              • >А это не apply, это именно init_by_array :)
                Ну тогда init_with_mt64. А ещё лучше init_with_mersenne_twister_64bit :D
                Ответить
                • > init_with_mt64
                  mt64_init_with_array(..)

                  А вообще class MersenneTwister, раз уж ОП запостил это в раздел с++ :)
                  Ответить
                  • на что только не идут люди, лишь бы не использовать boost.random
                    Ответить
                    • mersenne_twister_engine<UIntType,w,n,m,r,a,u,d,s,b,t,c,l,f>::result_type

                      Oh shi... Ну зато можно добавить свои параметры МТ, если стандартные mt19937 и mt11213b по какой-то причине не доставляют.
                      Ответить
      • > нн
        Ответить
    • Та нормально, для guess_the_number сойдёт.
      Ответить
    • std::mt19937_64
      Ответить

    Добавить комментарий