Школоло / Говнокод #3729 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
Function isEQ(x,y : Real) : Boolean;
Begin
if(x = y) Then isEQ := True Else isEQ := False;
End;


Begin
{...}
End.

Не выспался...

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

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

  • Паскалист бы написал
    isEQ := (x = y);

    А для вещественных лучше так:
    isEQ := (x - y) = 0;

    А c учётом вычислительных погрешностей:
    isEQ := abs(x - y) < eps * abs(x);
    (x = 0 особый случай).
    Здесь eps определено так, что 1 + eps = 1 в логике компилятора.

    Чувствую, сейчас кто-нибудь прибежит и крикнет: «Баян!»
    Ответить
    • isEQ := (x - y) = 0;
      - это не сработает.
      Нужно так:
      isEQ := (x - y) < некоторое_малое_значение;
      Ответить
      • Строчкой ниже я об этом написал: abs(x-y) < некоторое_малое_значение (именно abs, иначе не получится). Если взять константу, то числа с малым показателем будут почти всегда равны, поэтому некоторое_малое_значение должно быть пропорционально величине сравниваемых чисел.

        Пару раз наступил на грабли из-за машинного эпсилон, после чего сравниваю именно таким способом.
        Ответить
    • Дело в том, что это универ. Я сишник и повершельщик
      Ответить
      • если думать, что вещественные тоже набор битов, то теоретически прокатило бы. практически, действительно, нет - и не только на делфях
        Ответить
        • Для типов, укладывающихся в машинные слова прокатит только после принудительного изменения типа (в делфях/BP — move или запись с вариантными полями, в сях — memcpy или union). Пример:
          type hack = record
              case integer of:
                  1: f: Single;
                  2: i: Longint;
              end;
          end;
          
          var x, y: hack;
          ...
          isEQ := (x.i xor y.i) = 0;

          Или через указатели на память:
          type hack = ^Longint;
          ...
          isEQ :=  hack(@x)^ xor hack(@y)^ = 0;

          Жаль, не будет работать на значениях, только на переменных.
          Ответить
          • P.S. Не копируйте этот код! Он ничем не лучше прямого равенства. На практике он почти наверняка будет выдавать false.
            Ответить
            • Внезапно возникла идейка. Сравнивать порядки чисел и все биты мантиссы, кроме последнего. Тогда машинное эпсилон будет учтено. То есть после сравнения с помощью and вырезать младший бит мантиссы.
              Ответить
                • Вы так говорите об округлении, как будто это что-то плохое. На самом деле зависит от задачи. Теоретически округление может оказать и медвежью услугу. Вещественные числа ведь применяют в реализациях численных методов?
                  Ответить
                  • нет, я не говорю, что это плохо, я говорю только о том, что идейка не особо революционна
                    Ответить
                    • Согласен, что не ново, но работать будет побыстрее, чем abs(x-y) < epsilon.
                      Сравнение с округлением может споткнуться в случае, когда порядки разные, например, что-то типа 2 и 1,(9) или нормализованное число и денормализованное.
                      Ответить
                      • вряд ли оно будет быстрее, чем родное "x=y", которое транслируется всего в cmp x,y
                        так что предлагаю не задумываться о сравнении, а оставить на шаге битовых операций для вещественных чисел
                        Ответить
          • вот так мы расширили понятие битовых операций на множество вещественных чисел, подобно тому, как понятие логарифмов и корней расширяет понятие степени вне н-кратного умножения на себя.

            интересно, это может иметь какой-нибудь практический смысл, или судьба совершенных чисел повторится - красиво, но бесполезно?
            Ответить
            • Битовый сдвиг мантиссы и битовый сдвиг порядка приводят к разным эффектам, поэтому их надо выполнять отдельно, если мы, конечно, не пишем генератор псевдослучайных чисел. Страшно представить, что будет, если биты мантиссы въедут в биты порядка или наоборот. Аналогично и с другими операциями.
              Ответить
              • псевдослучайная последовательность - закономерная последовательность, закономерность которой неочевидна. То есть, это опять зависит от интеллекта индивида: нам с вами какая то последовательность может показаться случайной, а какой-нибудь гений выведет закономерность и будет на эту последовательность фыркать
                Ответить
                • Вот именно поэтому обычные псевдослучайные числа не годятся для криптографического метода «одноразовых блокнотов». Из-за применения псевдослучайности вместо случайности он становится потенциально вскрываемым.
                  Ответить
                  • вообще сложно сказать, что является "истинной" случайностью. Существует же некая теория детерминированности реальности, из которой следует, что даже классически предлагаемый способ бросать монетку - тоже будет генерировать не "случайные" "биты", а "псевдослучайные", пусть и с лучшим разбросом, а так же и более интересные выводы, такие, как
                    достаточно мощный компьютер может предказать будущее
                    время лишено мистицизма - в том утверждении, что "никто не знает, что будет" - и, возможно, все "существующее в будущем" - "уже" существует давно
                    Ответить
                  • и вообще, вся наука криптология основывается на достаточно субьективных понятиях типа "сложно (но можно)догадаться" и "долго считать", что значит, что в какой то момент развития вычислительных технологий она может крупно обосраться дискредитировать себя

                    но это уже уводит мысль в направлении о копирастии, что информация должна быть свободной )))
                    Ответить
                    • Криптология основывается на вполне объективных просчетах количества вычислений, необходимого для взлома (в зависимости от длины ключа).
                      И получается, что при достаточно длинном ключе не хватит не то, что времени на перебор, а еще и тупо энергии, даже если злоумышленник умудрится запитать свой мегакомп от Солнца. Тут уж как технологии не развивай - не вскроешь.
                      А еще можно вспомнить о "сроке годности" информации - через год взлома перебором скрытая информация может запросто потерять свою ценность.
                      Ответить
            • Int64 лучше. У меня была просто иллюстрация.
              А для типа Extended (80 бит) придётся вводить ^array[0..9]of Byte или ^array[0..4]of SmallWord и ксорить по частям.
              Ответить
              • Количество и разнообразие костылей как бы намекает нам на порочность самой идеи, нет?
                Ответить
                • у меня дача на костылях держится, но это не говорит о порочности дачи
                  Ответить
                    • За такой подход тоже, что говорит о его непорочности => дача тоже непорочная
                      Ответить
          • а с учетом погрешности
            type hack = ^Longint;
            var t: longint;
            ...
            t := hack(@x)^ - hack(@y)^;
            if (t < 0) then t := -t;
            isEQ := t < (1 shl n); // n - точность. чем меньше, тем точнее. погрешность в мантиссе, а знак и экспонента должны совпадать.
            ну случай с нулем отдельно нужно обрабатывать.
            и на значениях работать будет 😉
            Ответить
        • Но на практике такое сравнение будет абсолютно бесполезным по причине машинного эпсилон. Например, 10 + 1 / 2 может оказаться не равным 10.5.
          Ответить
          • вообще битовые операции имеют только битовый смысл - для всяких там флагов. Алгебраического смысла они не несут, за исключением всяких применений и побочных эффектов - вот как в сравнении исключением.
            я о том, что, например, 2 and 3 не представляется таким же понятным действием, как, например 2 + 3. тогда как даже тригонометрические функции хорошо представимы соотношением углов и сторон треугольника, комплексные числа - как двумерная числовая величина, и т.д.
            Ответить
            • А как же умножение и деление на 2 при помощи "<<" и ">>"? Очень даже алгебраичное применение и применяется такой способ очень часто.
              Ответить
          • но мы же сравниваем битовое представление чисел, а из за машинного эпсилон, именно битовое 10.5 может оказаться неравным результату выражения 10 + 1 / 2

            но для хора вещественных - самое то, что надо, браво инканус!
            Ответить

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

Переведи на "PHP", guest!

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


    8