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

    +17

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    unsigned long f( unsigned long a ) {
     while( (1 << 24) < a )
      a -= (1 << 24);
     return a;
    }

    Найден в дебрях старого проекта. Цель непонятна. Предположение -- обнулить старших 8-мь бит в 32-х битовом числе.

    Запостил: eao197, 13 Августа 2009

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

    • Ну, вообще, long может быть и 64-битным, т.е. функция этой функции (извиняюсь за тафталогию) в том чтобы опустить старший байт (если всё число не равняется "1 << 24") до третьего байта, со всеми вытекающими последствиями для остальных байт. (А в случае если всё число равняется "1 << 24" то опустить старший байт до 4-го)
      Ответить
      • с какого бока long будет 64 битным?
        size_t - будет, а long - ни разу.
        Ответить
        • С такого, что Вы, похоже, никогда не программировали под 64-битными системами.

          Проводим эксперимент:
          okunev@mail:~$ cat >t.c
          #include <stdio.h>
          
          int main() {
                  printf("%li\n", sizeof(long));
                  return 0;
          }
          
          okunev@mail:~$ gcc t.c; ./a.out 
          8

          А 8 * 8 == 64, что значит переменная 64-битная. Вы никогда не задавались вопросом, чем отличается long long от простого long?
          Ответить
          • под 64 бита не компилял, это правда.
            чем отличается long long от long на x32- знаю, на x64 - теперь не знаю :)
            до этого был убежден, что только размер типа указателя стал несовместим с int на x64.
            Ответить
            • По поводу long long и long... Впринципе, Вы уже вроде и сами разобрались long - это просто вариант, который использует максимальную битность при 32/64-битных машинах, а int и long long - это переменные фиксированного размера. :)
              Ответить
              • говорят что это все от глюкавого мелкософта, long long was only standardized due to pressure from Microsoft who can't for some reason implement an LP64 model
                Ответить
          • провел ресерч - все гораздо ужаснее
            http://software.intel.com/en-us/articles/size-of-long-integer-type-on-different-architecture-and-os/
            Ответить
            • Ну не гараздо ужаснее, просто мелкомягкие как всегда решили стать исключением :)..

              Но признаюсь, был не вкурсе что они ведут себя по-своему :(, ибо их ПО вообще не использую.
              Ответить
          • Не совсем все так.
            int имеет размер, зависящий от платформы (в соответствии со стандартом ISO C):
            An object declared as type signed char occupies the same amount of storage as a ‘‘plain’’ char object. A ‘‘plain’’ int object has the natural size suggested by the architecture of the execution environment (large enough to contain any value in the range INT_MIN to INT_MAX as defined in the header <limits.h>).
            Ответить
            • Да, я в курсе что int в платформах ниже 64-бит тупо принимает длинну равную битности системы. Просто у меня привычка думать только об UNIX-системах, а среди них 16-битной является только MINIX, которым никто не пользуется)

              Хотя формально я высказался неверно, конечно, спасибо за поправку.
              Ответить
        • На случай если я пояснил неисчерпывающе, то допоясню. Что sizeof(long) == 4 на 32-битной системе и sizeof(long) == 8 на 64-битной системе.

          Да, и вы никогда не задавались вопросом, чем отличается long от int? :)
          Ответить
      • Случай с "1 << 24" я неверно сформулировал, но, надеюсь, все поняли, что я имел в виду.
        Ответить
      • Насколько я смог понять, никакого опускания старшего байта нет. Есть его обнуление через вычитание единицы. Например, для числа 0x3000001, получаем последовательно на каждой итерации: 0x2000001, 0x1000001, 0x000001. Поэтому чем больше число, тем больше итераций. На 64-х битовых long-ах этот цикл вообще может зависать очень надолго ;)
        Ответить
        • Вы правы. Я с просони что-то не так прочёл, похоже :)
          Ответить
          • Но, как оказалось, я не так прав, как хотелось бы :(
            Для чисел, кратных 0x1000000 этот код будет уменьшать их до 0x1000000. Так что благодоря вашему замечанию я увидел эту особенность :)
            Ответить
            • Между прочим в вашем примере ошибки небыло, ибо Вы в последнем байте держали единицу ;)
              Ответить
    • Самое смешное, что Йоды магистра стиль тут применён строгого неравенства ради.
      Ответить

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