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

    −2

    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
    //сравниваем два числа, функция не использует операторы < и > в целях переносимости на платформы, где они не поддерживаются
    auto intcmp( int a, int b ) -> int {
    	while( a && b ) {
    		a--;
    		b--;
    	}
    	if ( a == 0 && b == 0 ) // числа равны
    		return 0;
    	if ( a == 0 ) // a - меньше 
    		return -1;
    	if ( b == 0 ) // a - больше
    		return 1;
    	assert( true ); // да нам подсунули какие-то неправильные числа
    }

    К слову "auto foo( ... ) -> type" добавили в C++11.

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

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

    • Можно было и трушнее записать:

      if ( a == b ) return 0;
      while ...
      if ( a == 0 ) return -1;
      return 1;

      Но такая версия не перехватит "неправильные" числа.
      Ответить
    • > в целях переносимости на платформы, где они не поддерживаются
      На машины тьюринга что-ли? Не могу представить себе контроллер на котором нет даже вычитания выставляющего флаги переполнения и нуля.
      Ответить
      • Надо у автора спросить. А ещё выяснить за что он отрицательные числа не любит.
        Ответить
      • Да даже если без флагов, всегда можно посмотреть, какое число получилось после вычитания.
        Ответить
      • >машины Тьюринга
        Ишь чего захотели!
        Арифмометра Феликс Эдмундыч с вас хватит! Со встроенным C++ компилятором ;)
        Ответить
      • Тоже стало интересно, но не менее интересно стало а что если и правда у нас нет <>? А что если и на битовую маску полагаться нельзя? :) a-b само-собой, а вот дальше сравнение знака заставило засохшие мозги поскрипеть :( Но в итоге получилось такое:
        // (d-1)/d gives 1 or 2 if d < 0 (e.g. -2/-1) = then a<b; 0 otherwise = a>b :
        return (a = a - b)
            ? ((int)((a - 1) / a) ? -1 : 1)
            : 0;
        Ответить
        • Интересное решение. Работает с отрицательными числами?
          Ответить
          • Конечно, иначе чего-б я пыхтел? :) Хотя я не гарантирую 100% рабочести при крайних значениях, я уже лет 6 или 7 к плюсам не прикасался... Например я сомневаюсь в результате если a будет минимальным (минус сколько там...2 миллиарда?), а b будет любым положительным... Переполнение ведь получу? ...разница выйдет положительной, и результат выдаст +1=a>b.

            РНР таки съедает мозги...
            Ответить
        • Красиво. Но тут деление. А если уж на этом "процессоре" нет сравнений - то умножений и делений на нем нет и подавно.
          Ответить
          • Нужна своя реализация деления вычитанием.
            А вычитание декрементом.
            А декремент... ну если на платформе нет и декремента, C++ компилятора под такую платформу и подавно нет.
            Ответить
            • > C++ компилятора под такую платформу и подавно нет
              Как и под платформу где нельзя запилить операторы < и > ;)
              Ответить
            • Декремент есть всегда, по определению машины тьюринга.
              Ответить
              • В определении машины Тьюринга произвольная конечная алгебра фигурирует. Почему бы не быть алгебре без декрементов?

                В некотором смысле в машине Поста есть декремент всегда: из меченого в немеченый :)

                (j/k)
                Ответить
      • I'm not wothry to be in the same forum. ROTFL
        Ответить
      • It's a <a href="http://svgmea.com">plsauere</a> to find someone who can think so clearly
        Ответить
      • AFAICT you've coevred all the bases with this answer! http://ifpahk.com [url=http://igwpdqwh.com]igwpdqwh[/url] [link=http://fnwggrcx.com]fnwggrcx[/link]
        Ответить
      • That's an apt answer to an inestreting question http://gagiba.com [url=http://zaewwythznd.com]zaewwythznd[/url] [link=http://jrlrbwuffj.com]jrlrbwuffj[/link]
        Ответить
    • Нету таких платформ
      Ответить
      • А вдруг? Автор вон активно новый стандарт эксплуатирует, видно что толковый программист.
        Ответить
      • на спектруме :) не было сравнения на "больше-меньше". была только проверка переполнения.
        а современные платформы?
        Ответить
        • Но вычитание то с проверкой переполнения всяко было... Так что компилятор вполне может сэмулировать операторы < и >. А если не может - то он для этой платформы просто не должен существовать.
          Ответить
          • это уж точно.
            не нужно пытаться объять необъятное (с)
            Ответить
            • ... постичь непостижимое и впихнуть невпихуемое ;-)
              Ответить
    • Зато этот код легко переписывается на брейфак.
      Наверное.
      Ответить
      • Наиболее вероятно, что код уже был переписан...
        С брейнфака на си.
        А затем и на си++, путём добавления auto и стрелочки.
        Ответить
    • assert( true );
      Ответить
      • Да ладно тебе.
        >>> платформы, где они не поддерживаются
        >>> операторы < и > [в ЯВУ С++ );]
        На фоне этого незнание логики ассерта меркнет
        Ответить
        • Оуууу. Спасибо, не заметил.
          Видимо это причина того, что неправильные числа не палились до сих пор.
          Ответить
    • Про такие платформы не знаю, а вот архитектуры с ограниченным количеством мат.оп.
      точно есть, но пишут для них, как правило, на асме.
      Вот там раздолье для битоманипуляций.
      Ответить
      • That's the thniking of a creative mind
        Ответить
      • Yeah that's what I'm talking about <a href="http://wdqphsffe.com">ba-bi-nyce</a> work!
        Ответить
      • I di'ndt know where to find this info then kaboom it was here. http://jmwvnitedn.com [url=http://vcxgnlm.com]vcxgnlm[/url] [link=http://rmlckh.com]rmlckh[/link]
        Ответить
      • Full of salient points. Don't stop beeivling or writing! http://bnmisyirnxg.com [url=http://wddamqy.com]wddamqy[/url] [link=http://ykyzbrvcay.com]ykyzbrvcay[/link]
        Ответить
    • Вспомнилась народная история про бета-чай.
      Теплопроводность сковородки для жарки кофейных зерен по умолчанию установлена в ноль для совместимости с другими вселенными, в которых законы физики могут оказаться иными...
      Ответить
    • Наверное одна из таргет-платформ это BrainfuckVM. Там >< не поддерживается.
      Ответить
      • Как это нету? Все там поддерживается:

        < - перейти к предыдущей ячейке
        > - перейти к следующей ячейке
        Ответить
        • Смешно да, но в брейнфаке как раз сравнивают числа как раз через цикл до обнуления.
          Ответить
          • А как с отрицательными числами? Ждём переполнения?
            Ответить
            • Видимо через цикл до INT_MIN. Так и signed числа корректно сравниваются.
              Ответить
    • Шедеврально
      Ответить
    • для положительных (для отрицательных можно доделать) идея такая:
      if ((a ^ b) & 0x4000){
      if (a & 0x4000) return 1; else return -1;
      }
      if ((a ^ b) & 0x2000){
      if (a & 0x2000) return 1; else return -1;
      }
      if ((a ^ b) & 0x1000){
      if (a & 0x1000) return 1; else return -1;
      }
      ....
      if ((a ^ b) & 0x1){
      if (a & 0x1) return 1; else return -1;
      }
      return 0;
      // если сдвиг есть, то мона в цикле
      Ответить
      • Да. Хороший алгоритм. O(log(n)) против O(n) у ОПа.

        А для правильной работы с отрицательными вроде бы достаточно прибавить к a и b 0x8000, тем самым сместив диапазон с -32768..32767 в 0..65535?
        Ответить
        • ну по идее должно. по крайней мере для привычной архитектуры.
          Ответить
          • В принципе, должно работать и вот так.
            Для unsigned:
            if ((a ^ b) & 0x8000) {
                if (a & 0x8000) return 1; else return -1;
            }
            ... дальше как было ...

            Для signed:
            if ((a ^ b) & 0x8000) {
                if (a & 0x8000) return -1; else return 1;
            }
            ... дальше как было ...
            Ответить
        • Тогда сложность будет O(n + 0x8000). Тоже O(n), но на практике же жопа.
          Для сравнения 1 и 0 например 0х8000 операций надо.
          Ответить
          • Уточню только что с точки зрения сложности:
            O(f(x) + const) = O(f(x)).
            А с практической точки зрения эта const может вылиться в смертельные тормоза.
            Ответить
            • Чего? У этого чипа нет и сложения? И увеличивать на 0x8000 нужно путем 0x8000 инкрементов?

              Окай. a ^= 0x8000, b ^= 0x8000. Результат такой же. Надеюсь, что хотя бы xor там есть...
              Ответить
              • Да нет. Я к тому что если в оригинальном алгоритме автора прибавить 0х8000 к a и b, понадобится на 0x8000 больше декрементов если числа были положительные.

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

                Например сравнение 1 и 0 раньше требовало 0 декрементов, а теперь это будет сравнение 0x8001 и 0x8000, так что декрементов будет намного больше.
                Ответить
                • Ну я не к алгоритму автора предлагал прибавлять, а к алгоритму ctm. А если к алгоритму автора - то среднее число декрементов остается тем же - 0x8000.
                  Ответить
                • Вы только что всем доказали, что сложность алгоритма с линейной сложностью растёт линейно.
                  Ответить
                  • Осталось доказать, что логарифмический алгоритм растет логарифмически.
                    Ответить
                  • Извиняюсь если это так выглядело. Для меня О-большое не такая простая вещь, могу иногда пытаться объяснить то, что даже дети понимают.

                    Больше хотелось показать что без прибавления числа в начале алгоритм эффективнее для чисел близких к 0.

                    Тут выбор того сколько прибавлять будет зависеть от того, какие числа чаще должны сравниваться.
                    Ответить
                    • > Больше хотелось показать что без прибавления числа в начале алгоритм эффективнее для чисел близких к 0.
                      Зато не эффективнее для отрицательных...

                      > будет зависеть от того, какие числа чаще должны сравниваться.
                      Ну да, тут согласен.
                      Ответить
    • И кстати. Нужно реализовать всё так:

      Сложение инкрементом.
      Умножение таким сложением.
      Возведение в степень таким умножением.

      Ну и посчитать 5^3
      Ответить
      • Ага. А числа представить в виде нумералов чёрча.
        Ответить
      • У нас на лабах по асму было что-то подобное, сложение слов без арифметических операций, потом сложение больших чисел, затем умножение и деление. Жуткий говнокод получался.
        Ответить
        • Откопал сложение http://govnokod.ru/11313
          Ответить
        • Блин, мне бы ваши лабы... А у нас на асме были банальные "вычислите формулу в духе x*y+z", "запилите менюшку" да "поработайте с текстовым или двоичным файлом" ;(
          Ответить
          • менюшку на асме?
            мне институтский ассемблер запомнился реализацией некоторых криптоалгоритмов, защищенных от атаки по времени и с обфускацией (любая ветка if обязана иметь примерно одинаковое количество тактов - независимость времени алгоритма от входных данных, при этом делать что то более осознанное и правдоподобное, чем nop) - было интересно, и как то надо было на асме читать конфигурационный файл, я запилил парсинг ini-подобного формата
            после института ассемблер все равно не пригодился, но уж лучше его, чем ненужную машину тьюринга
            Ответить
            • > менюшку на асме?
              У нас и на лабах по прологу были тупые базы данных, и, внимание, вычисление функции через ряд(!), вместо того, чтобы попробовать порешать на нем какие-нибудь логические задачки... Что поделать, сибирская глубинка.

              > реализацией некоторых криптоалгоритмов
              Вот. Вот это действительно интересная лаба.

              > более осознанное и правдоподобное, чем nop
              А вот это, походу, уже не от атаки по времени, а от атаки замером потребляемого тока ;) К PC она, конечно, не применима, но вот к чипу с внешним питанием, типа той же симки - вполне реальна.

              > после института ассемблер все равно не пригодился
              Ну да, сам по себе он сейчас не особо нужен. Разве что для чтения дизасма... Но зато его изучение помогает разобраться в принципах работы компа.
              Ответить
              • > У нас и на лабах по прологу
                > сибирская глубинка
                У нас пролога вообще не было. :( Город большой, но в плане образования не очень. Я, конечно, очень благодарен родному универу за бесплатное (в целом вполне неплохое) образование, которое получил, но минусов довольно много. ASM был, ковыряли всякие несложные задачки типа "распарсить и сложить числа, прочитанные с консоли". Хорошо хоть, что препод заставлял объяснять содержимое каждого регистра и кадра стека после каждой инструкции. С тех пор ассемблера особо не видел.
                Ответить
          • У нас у кого-то в качестве курсовой (sic!) по ассемблеру было что-то в духе "выведите в окно текущее дату и время". Такие дела.
            Ответить
            • Why do I bother caillng up people when I can just read this!
              Ответить
            • A good many <a href="http://lrzlzpucm.com">vaueballs</a> you've given me.
              Ответить
            • I love reading these articles because they're short but intfamroive. http://qfpnmudioku.com [url=http://puxtevh.com]puxtevh[/url] [link=http://fuytjqi.com]fuytjqi[/link]
              Ответить
            • This info is the cat's paamajs! http://dqneuheeifc.com [url=http://udeopv.com]udeopv[/url] [link=http://crfmgxfki.com]crfmgxfki[/link]
              Ответить
      • Эт ерунда, мы по дискретному анализу писали вычисление n-ого знака числа e (и прочие вкусности) на обычной машине Тьюринга, лично я делал вычисление n-ого простого числа. До сих пор с болью вспоминаю.
        Ответить
        • Где можно почитать на тему вычисления n-ого знака иррациональных чисел?
          Ответить
          • Я не в курсе, такую задачу не решал. Первое, что приходит в голову: искать разложение в ряд с известной оценкой ошибки. Мои товарищи так и делали, когда n-ый знак числа e находили.
            Ответить
            • Для числа пи, если мне не изменяет память, есть такая формула.
              Ответить
            • Ну т.е. нельзя просто написать в цикле save_pi_digit( i ); и через 20 лет установить рекорд?
              Ответить

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