1. Си / Говнокод #7780

    +146

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    case '16':
                dm("sixteenth");
                *b_=FULL_NOTE_DURATION_TCK/16 & 0x0F;
                *c_=(FULL_NOTE_DURATION_TCK/16 & 0xF0) >> 8;
            break;

    Человек парсил хексы из строки и задумался немного при копировании блоков в свитче.

    Запостил: m08pvv, 05 Сентября 2011

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

    • деление тоже надо было заменить сдвигом
      Ответить
      • сдвигом автора
        Ответить
      • Кстати, есть такой прикол: деление и сдвиг делают разный результат.
        Ответить
        • есть ньюансы. например, знаковый бит.
          Ответить
          • Знаковый бит разруливается командой sar, но ньюансов больше.
            Например, ботланд вообще забил на корректность сдвига для знаковых типов, поэтому лепит shr одинаково для знаковых и беззнаковых типов (нормальные люди для знаковых типов делают sar):http://www.gamedev.ru/code/forum/?id=138759, самый ржач, когда код -7 shr 1 получает что-то очень большое, а в отладчике показывается -4.
            Но даже sar означает не то же самое, что интеловское деление.
            Например, -1 >> 1 будет равно -1, собственно, как и требуется по правилам арифметики (http://ru.wikipedia.org/wiki/Деление_с_остатком, обратие внимание на 0<=r), но идиоты из интела зачем-то сделали для этого случая отрицательный остаток, и это пиздец как неудобно - например я хочу координаты объекта перевести в номер занимаемой ячейки, я делю на 100, и получаю неверный номер для отрицательных чисел.
            Ответить
            • что-то сегодня Тарас негодует на борланд
              Ответить
              • Ты ту тему до конца дочитай, там под конец эпичный слив (не мой).
                Ответить
            • http://www.gamedev.ru/code/forum/?id=138759&page=12#m166
              Ответить
              • В этой теме я, кстати, не троллил.
                Я троллил тут: http://www.gamedev.ru/code/forum/?id=139163
                Ответить
                • Вам бы жену найти, а не разводить компиляторы...
                  Ответить
                • Троллинг на уровне ассемблерных инструкций с почти одинаковым смыслом, но разными названиями - зачётный. Сколько народа повелось... А главное на сколько страниц... Ъ
                  Ответить
                • http://www.gamedev.ru/code/forum/?id=139163&page=8#m105
                  Ответить
                • Круто! Ничего сравнимого с этим не видел. Не думал, что можно такое развести из SHL/SAL.

                  Может быть, в Луркоморье запостить?
                  Ответить
                • Тонко.
                  Ответить
                • TarasB был бы на Марсе...
                  Ответить
                  • Не был, но слетал бы, если бы не дебажил сутками свои проги, бедняга. Язык на присваиваниях у нас уже есть, пусть Тарас продвигает принципиально новый язык на побитовых сдвигах!
                    раз он их так любит
                    Ответить
            • ISO/IEC 14882:2003 : Programming languages -- C++, 5.6.4: ISO, IEC, 2003 . «the binary % operator yields the remainder from the division of the first expression by the second. …. If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined»

              далее
              5.8.3
              The value of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a non-negative value, the value of the result is the integral part of the quotient of E1/2^E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined

              слив не мой, я просто разместил объяву
              Ответить
              • В C++11 уже не implementation-defined.
                Ответить
                • да для operator%() уже нет. результат operator/() всегда должен округляться к нулю

                  т.е. -43 = 6 * (-7) + (-1) и 43 = (-6) * (-7) + 1 тру
                  -43 = 7 * (-7) + (6) и 43 = (-7) * (-7) + (-6) не тру

                  касательно 5.8.3 - это взято из "Working Draft" нового стандарта. если есть че поновей, будь добр, кинь ссылку
                  Ответить
                  • Сдвиг отрицательных всё так же implementation-defined.

                    Новее N3242 вроде в публичном доступе нет.
                    Ответить
    • что за '16'?
      Ответить
      • показать все, что скрыто0xF, возраст автора
        Ответить
        • 0xF = 15
          '16' - это мульти-символьный литерал, они зависят от реализации и не рекомендуются к использованию (gcc ругается ворнингами). Ведёт он себя довольно весело:
          #include <stdio.h>
          int main() {
            printf("'16' is %d", '16');
            return 0;
          }
          выводит <<'16' is 12598>>, а
          #include <stdio.h>
          int main() {
            char a = '16';
            printf("'16' is %d", a);
            return 0;
          }
          выводит <<'16' is 54>>
          Ответить
          • > '16' is 54
            круто
            Ответить
            • Всё элементарно: 54 = 0x36 = '6'.
              Все символы, кроме последнего, как заметил absolut, игнорируются. По идее так должно быть только на Little Endian. Надо проверить на Big Endian и сравнить. Если моя гипотеза верна, то
              '16' == '6' на little endian;
              '16' == '1' на big endian.
              Следовательно, у нас хакерский код для определения порядка байтов.
              Ответить
          • Так ... а почему %d во втором случае? Так и однобайтные литералы будут "веселые" результаты выводить.
            И вообще, char a='16'; char b='q6'; char c='xyz6'; дают одинаковые результаты из-за усечения.
            Ответить
            • Вы правы, но, к счастью, %c ведёт себя в этом случае также, как и %d.
              Понятно, что дело в отсечении: 0x3136 не помещается в char. В этом весь смысл "примера". В общем, автор кода явно разместил в case совсем не то, что нужно.
              Ответить
          • 'x' в C — это константа типа не char, а int. '16' равно здесь ('1'<<8)+'6' = (49<<8)+54 = 12598 (в других реализациях может быть иначе). (char)12598 = 54.
            Ответить
        • Садитесь, ставлю вам двойку.
          ПыСы: двойка - это 2, а не 1! Радуйтесь.
          Ответить
        • Нифига. :-) Мне почти двадцать. xDDD

          А чего вы хотели от уставшего человека посреди ночи? xD Сам ржал с этого. xDDD
          Ответить
      • 'x' в C — это константа типа не char, а int. '16' равно здесь ('1'<<8)+'6' = (49<<8)+54 = 12598.
        Ответить

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