"PHP" / Говнокод #27506 Ссылка на оригинал

+1

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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
  24. 24
$a != abs($a)
$a+abs($a) == 0
$a && !($a + abs($a))
$n>>1 > $n
substr_count($a,"-")
is_nan(sqrt($number))
is_nan(log($n))
!array_shift(explode("-", $num))
(int)$var === ~~(int)$var
strlen(strval($num)) != strlen(strval(abs($num)))
strlen(decbin($n)) == 32
is_int(strpos(get_headers("http://habrahabr.ru/blogs/php/page$num/")[0], '404'));

function lessThanZero ($num) {
    while (1) {
        if ($num++ == 0) {
            return true;
        }
    }
}

function is_value_between($value, $begin, $end) {
    return in_array($value, range($begin,$end));
}

"Как проверять отрицательное ли число ?
В мануале в математических функциях не нашёл ."

https://php.ru/forum/threads/kak-proverjat-otricatelnoe-li-chislo.8208/

Запостил: kezzyhko kezzyhko, (Updated )

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

    • > Особенно условие завершения.

      gcc на них нет:
      lessThanZero:
          mov eax, 1
          ret
      Ответить
        • И то и другое.

          Оно вернёт true или переполнит int.

          Оно вернёт true или повиснет нахуй.

          Т.е. даже с unsigned это тупо return true. И даже если в цикле не инкрементить, то один фиг return true.

          З.Ы. Нефиг писать функции, которые возвращают только одно значение )))
          Ответить
        • И зацикливание и переполнение знакового — UB. Так как компилятор по умолчанию считает программиста компетентным, то компилятор рассматривает случае, когда UB не возникает. В данном случае вариант один — если num уже 0.

          Если бы num было беззнаковым, тогда всё просто — в конце концов num переполнится и станет равным 0.

          Если бы знаковое переполнение не было бы UB — то же самое.
          Ответить
          • > в конце концов num переполнится

            Убери инкремент и он всё равно выкинет... Либо num уже ноль и мы вернём true либо всё повиснет и нам пофиг, можно тоже вернуть true.
            Ответить
          • > компилятор рассматривает случае, когда UB не возникает

            Программа B называется аппроксимацией программы A, если для всех случаев, в которых A завершается B завершается с тем же результатом.
            Ответить
            • Если в программе А в каких-то случаях возникает UB, то любое поведение программы B в этих случаях будет корректным, поэтому эти случаи можно не рассматривать. Кстати, где-то был говнокод, где в цикле обходился массив, и выходило, что возвращается либо 4 (вроде), либо что-то другое, но после выхода за границы массива. Компилятор оптимизировал это в return 4; — единственный не-UB результат.
              Ответить
              • Не совсем, поведение UB'ов не описано в сёмантике языка. Вообще. Т.е. формальный интерпретатор не сможет перейти в следующий стейт и никогда не сможет доползти до завершающего.

                Т.е. формально любой UB эквивалентен зависанию.

                Именно поэтому мы можем аппроксимировать программу с UB'ом при помощи более простой программы, которая забивает на поведение под UB'ом.

                > за границы массива

                Это я вроде постила.
                Ответить
  • Первые два способа неэквивалентны. Или "PHP" и здесь чудит?
    Ответить
  • > В мануале в математических функциях не нашёл .

    Может еще нужно чтоб была особая функция для проверки равенства нулю?
    Ответить
            • Почему бигинты из коробки есть, а arbitrary-precision floating point arithmetic нет?
              Ответить
              • Как нят, когда есть?
                >>> import decimal
                >>> decimal.getcontext().prec = 1000
                >>> decimal.Decimal(2).sqrt()
                Decimal('1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641572735013846230912297024924836055850737212644121497099935831413222665927505592755799950501152782060571470109559971605970274534596862014728517418640889198609552329230484308714321450839762603627995251407989687253396546331808829640620615258352395054745750287759961729835575220337531857011354374603408498847160386899970699004815030544027790316454247823068492936918621580578463111596668713013015618568987237235288509264861249497715421833420428568606014682472077143585487415565706967765372022648544701585880162075847492265722600208558446652145839889394437092659180031138824646815708263010059485870400318648034219489727829064104507263688131373985525611732204024509122770022694112757362728049573810896750401836986836845072579936472906076299694138047565482372899718032680247442062926912485905218100445984215059112024944134172853147810580360337107730918286931471017111168391658172688941975871658215212822951848847')
                Ответить
                • Нечестно! У тебя длинная константа записана строкой.

                  На уровне языка можно так записать?
                  Ответить
                  • У меня длинная константа записана результатом вычисления корня с произвольной точностью — в данном случае с точностью до одной тысячи десятичных зняков после запятой.

                    Модуль decimal является частью стандартной библиотеки языка.
                    Ответить
                    • Я и в «PHP» так могу:
                      <?php
                      bcscale(1000);
                      echo bcsqrt(2);


                      «bcmath» в поставку входит, но в «Ideone» его почему-то не включили.
                      Ответить
                      • P.S. В пэхапэшном модуле «bcmath» неудобно сделали, что точность задаётся глобально. А в «Питоне» можно создать несколько контекстов с разной точностью?
                        Ответить
                        • > в питоне

                          Ну да, можешь локальный контекст открыть и посчитать что-то, если глобальный крутить не хочется.
                          Ответить
    • Т.е. если я сравню потом его с нулём, у меня получится false т.к. -0 < 0? А нет, нули всё-таки равны.
      Ответить
      • В JS числовой тип запутанный. Хотя носителем является double, всё сделано так, чтобы он был неотличим от целого, если близок к целому. Поэтому и ноль один.
        Ответить
      • <?php
        
        printf("%d\n", "0" == "-0"); // 1
        printf("%d\n", "0" == "0"); // 1
        printf("%d\n", "0" === "-0"); // 0
        printf("%d\n", "0" === "0"); // 1
        
        ?>

        В каком еще языке есть такая хер-ня?
        Ответить
          • А много ли таких языков? В JS например такая херня тоже есть. А где еще?
            Ответить
            • Я только два знаю.

              === есть в Яибу, но там он означает совсем другое. Кто, не подглядывая в справку, вспомнит его значение?
              Ответить
              • "===" в яибе имеет миллион смыслов. И проверка на range (как in) и на регулярку (как =~) и вроде на принадлежность классу

                Это просто перегруженный у разных говнов оператор, и он не коммутативен
                Ответить
                  • А что не так? Я ожидал, что «Руби» говно, так и получается.
                    Ответить
                  • максимально ожидаемое для рубиста

                    хотя мне этот оператор тоже не нравица
                    Ответить
                    • > максимально ожидаемое для рубиста

                      Т.е. в с++ всё тоже норм т.к. "максимально ожидаемо для полностью изучившего стандарт"?
                      Ответить
                      • > максимально ожидаемо для полностью изучившего стандарт

                        То есть, никем не ожидаемое?
                        Ответить
                      • В С++ очень много костыликов ради совместимости, руби в этом плане чуть проще ,конечно
                        Ответить
                • И вроде там слева нужно ставить известное значение (чтобы интерпретатор выбрал нужную перегрузку), а справа — проверяемое, поэтому получается йода-стайл.
                  Ответить
                  • именно
                    #
                    irb(main):004:0* "A" === String
                    => false
                    irb(main):005:0> String === "A"
                    => true

                    потому я за "яuбy"
                    Ответить
          • Кстати, даже в JS такой херни нет
            importPackage(java.io);
            importPackage(java.lang);
            
            System.out.println("0" == "-0"); // false
            System.out.println("0" == "0");  // true
            System.out.println("0" === "-0"); // false
            System.out.println("0" === "0"); // true

            https://ideone.com/Wsigk8

            PHP зачем-то при "0" == "-0" и "0" == "0" кастует эти "0" "-0" в числа и потом сравнивает, а при === сравнивает их как строки. Нахуя так надо делать?
            Ответить
            • > PHP зачем-то при "0" == "-0" и "0" == "0" кастует эти "0" "-0" в числа и потом сравнивает, а при === сравнивает их как строки.
              Так это давняя смешнявка. Пых (справедливо) считает, что по умочанию ня нём программирует ротоняк, который про эти ваши "типы" ня задумывается, поэтому оператор "==" пытается аргументы-строки привести к числам. В каком-то, кажется, пятом пыхе вообще была встроенная уязвимость, благодаря которой все строки, нячинающиеся с "0e", считались равными. Представь, как это отразилось ня коде пыхомакак, которые сравнивали хэши паролей пользователей через PHP.
              Ответить
        • Где тут херня? В первых двух случаях происходит преобразование в числовой тип, поэтому они равны, в третьем сравниваются *строки*, они разные, а в четвёртом, также строки, но они одинаковы.
          Ответить
          • В голове у того, кто придумал эту механику сравнений...

            Если бы == всегда кастовал в числа, как в том же пёрле, было бы просто и логично. Но это ведь не так. Оно иногда в строки кастует, иногда в числа, ещё и в разных версиях эта эвристика работает по-разному.
            Ответить
            • Профит от него есть, особенно если надо сравнивать кусок строки, в котором находится число, с другим числом. Так что, думаю, его создали из благих побуждений.

              Но этот оператор чаще всего используется при сравнении массивов, где он-то удобен.
              Ответить
              • > кусок строки, в котором находится число, с другим числом

                "php" == 0
                Ответить
                  • Кокококой кокококошмар!

                    Именно поэтому я не люблю полагаться на неявное приведение, а предпочитаю использовать === и явный вызов strval, intval, floatval etc.
                    Ответить
                    • >Именно поэтому я не люблю полагаться на неявное приведение, а предпочитаю использовать ===

                      Согласен, это предпочтительнее.

                      >явный вызов strval, intval, floatval etc

                      А тут я больше привык к (string) и тд. Смысл не меняется.
                      Ответить
    • При возведении большого положительного флоата в квадрат, может получиться inf, а извлечение квадратного корня из inf дает inf. К тому же возможны всякие ошибки округления и тогда равенства не будет и при положительных без всяких inf. К тому же если это не флоаты а инты конечной разрядности, возможно переполнение.
      Ответить

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

Семь раз отмерь — один отрежь, guest!

    А не использовать ли нам bbcode?


    8