В своей книге "Первобытное мышление" Люсьен Леви-Брюль рассказывает, как люди из первобытных обществ, даже прожившие долгое время в цивилизованном обществе, продолжают верить в колдунов и магию. Его теория состояла в том, что первобытные народы склонны к так называемому дологическому мышлению, тогда как представители современной цивилизации опираются в своих суждениях на логику. Леви-Брюль, однако, ошибался. Ниже я покажу, как люди из цивилизованного общества, получившие образование в ведущих ВУЗах страны, начинают верить в магию даже в той области, в которой они являются профессионалами. Имена, названия и высказывания изменены так, чтобы никто не нашёл себя и не обиделся.

Работал я тогда в компании среднего размера. Несмотря на средний размер, это была компания, которая продавала свой продукт в передовые страны запада, а это всё-таки показатель высокого качества. И работали там не простые программисты, а выпускники мехмата МГУ, МФТИ и прочих уважаемых ВУЗов. Но был в этой компании момент, который меня конкретно выбешивал: мне постоянно повторяли, что без особой необходимости не надо ничего менять. Как-то, помнится, нашёл я в коде строку

x = (a + b * c + d) * (g - sin(alpha) * cos(beta) ) * (cos(d5) + d8 + d11) / (k - t * p) / (d7 + d9 + d15);
y = (a + b * c + d) * (g - sin(alpha) * cos(beta) ) * (cos(d5) + d8 + d11) / (k - t * p) / (d7 + d9 + d15);
z = (a + b * c + d) * (g - sin(alpha) * cos(beta) ) * (cos(d5) + d8 + d11) / (k - t * p) / (d7 + d9 + d15);

Ну я взял и поменял на

x = y = z = (a + b * c + d) * (g - sin(alpha) * cos(beta) ) * (cos(d5) + d8 + d11) / (k - t * p) / (d7 + d9 + d15);

Не ускорения ради, а просто чтобы не мозолило глаз. Как на меня тогда напал наш группенфюрер...

Сейчас все модели сломаются! Потом скажут, что мы всё сломали! Я такие изменения не пропущу!

Продукт был довольно сложным вычислительным движком, поэтому каждое изменение проходило тестирование на так называемых моделях. Но как это моё изменение могло сломать тесты, я в упор не понимал. И вот однажды в процессе работы я нахожу такой вот код

if (fabs (mult - 1.) > std::numeric_limits::epsilon ())  // this is needed because x * 1. != x if x << 1
{
    factor *= mult;
}

Как мы видим, стоит проверка, что если отличие множителя от единицы меньше численной точности представления (примерно 16 знаков для double), то умножение не производится. С точки зрения любого разумного человека эта проверка является совершенно бессмысленной, хоть и довольно безвредной (если конечно не считать вредом то, что людей заставляют верить в магию умножения на единицу). Однако автор кода оставил для нас комментарий, почему эта проверка важна: мол если множитель равен 1, то лучше не умножать, потому что это может изменить умножаемое число, если это число мало. Писал, очевидно, человек, который не знает, что в представлении с плавающей запятой числа хранятся так, что их относительная точность не зависит от того, равно число 1.e+100 или 1.e-100.

Мне стало интересно, как могло родиться такое, и я начал читать соответствующий "тикет". Не знаю, смогу ли я передать невероятное напряжение, захватившее меня, но я чувствовал себя детективом, расследующим убийство в романе Агаты Кристи. Детективом, расследующим убийство разума.

Среди тестовых моделей была одна, при запуске которой программа падала. Стали выяснять почему и оказалось, что движок требовал памяти больше, чем имелось на машине. Как часто бывает в таких ситуациях, когда умные люди, не имея дельных предложений, молчат, находится ограниченный, который предлагает какую-то херню. И такой человек немедленно нашёлся. Назовём его Коля. Коля "исправил" проблему: при превышении размера имеющейся памяти программа стала корректно завершаться, а не просто падать. Кроме этого весомого вклада в решение Коля обратил внимание, что падающая модель невероятно сложна: содержит аж на три элемента больше, чем другие модели, движок не справляется и давайте использовать магическое слово "СЛОЖНАЯЗАДАЧА" для решения таких моделей. Как также обычно бывает, вместо того, чтобы сказать ограниченному, что он ограниченный, большинство соглашается с его предложениями, а умные люди продолжают молчать. Но оказалось, что модель всё равно продолжала падать, правда теперь уже на кластере.

Тут, как в книге Леви-Брюля, впору бы уже признать, что виноват колдун, который наслал порчу на кластер, но главный эксперт по кластерам Алик понял, что причина падения в том, что кластер пытался выделить слишком много памяти на NUMA-узле (хм... мне кажется, мы уже где-то это видели), и пообещал придумать, как защитить кластер от этого хитрого колдунства.

В этот момент вмешался технический директор и начал спрашивать, что мол никого не удивляет, с какого перепуга узлу потребовалось 70 гигов памяти, но ему быстро объяснили, что причина в страшной модели (в сочетании со страшным колдунством конечно же), и он перестал мешать людям бороться с колдунством: в модели что-то подкручивали, что-то меняли, но колдунское проклятие было слишком сильно и ничего не помогало. К концу года проблему так и не победили и просто перестали обращать на неё внимание. Однако через несколько месяцев (!) некто, назовём его Муся, сделал наброс на вентилятор, написав, что мол Вова своим множителем mult сломал модель. Это ключевой момент в истории, поэтому обратим внимание терпеливого читателя на то, что модель и без изменений Вовы не работала уже больше года. Просто после изменений Вовы она стала выплёвывать другие ошибки.

По-хорошему Вова мог бы призвать участников дискуссии к разуму и объяснить, что его изменения вообще не затрагивали тот кусок кода, где происходило падение, и что оно происходило и до его изменений. Но какой разум с этими людьми? И Вова нашёл наилучшее решение проблемы: поставил условие, что если множитель равен единице, то не надо домножать на этот множитель. И заодно вкатил туда псевдонаучное объяснение, что мол x * 1. != x. Однако это бессмысленное изменение сделало главное: проблемная модель снова стала глючить точь-в-точь, как глючила до этого.

В конечном итоге, ещё через несколько месяцев проблему решил человек, обнаруживший, что в параметрах модели допустили ошибку в одной из таблиц, в результате чего какая-то матрица вырождалась, обратная матрица не считалась, ну и далее всё шло по одному месту.

Итого: проблема решена, модель работает, и все верят в то, что маленькие числа лучше не умножать на единицу. Занавес.

P.S. Вот из-за таких случаев я всё больше утверждаюсь во мнении, что образование в ведущем ВУЗе вообще не гарантирует, что человек умный: иногда я вижу перед собой обезьян, которые умеют решать дифуры.

P.P.S. Если вы, прочитав мой текст, хотите спросить "а что не так?", сразу отвечу. Не так тут то, что проблему, к которой человек не имел никакого отношения, свалили на него, вынудив вставлять бредовую проверку близости числа к единице. И после того, как проблему нашли, надо было заняться написанием кода, который бы проверял тестовые модели на валидность данных, а бредятину убрать. Но проверку не сделали, а код, заставляющий верить в магию, оставили.

Комментарии (37)


  1. vkni
    30.12.2023 02:18
    +6

    образование в ведущем ВУЗе вообще не гарантирует, что человек умный

    Ну это трюизм. Но ум-то бывает совершенно разный, и действительно умный в определённой области человек, может быть совершенным идиотом в другой. Причём идиотом с убеждениями.


  1. slavanikolsky
    30.12.2023 02:18
    +4

    В программировании все индивидуально. Образование важно для страта, но дальше важнее практика и желание копаться с мелочами. Лично видел как по-разному подходили два программиста к коду. Один писал как учили в ВУЗе, а второй писал по функциональности, что требовало дополнительного описания ибо не сразу можно было «вкурить»)), но читать его код было одно удовольствие.


    1. saipr
      30.12.2023 02:18

      Да, все индивидуально:

      Обучение началось с изучения систем счисления. Всё что я знал до этого
      момента про счёт – это арабские и римские цифры. А оказалось, что в
      повседневной жизни мы пользуемся десятичной системой счисления, а вот
      для электронно-вычислительных машин это совсем не подходит и в них
      используется двоичная система счисления, состоящая из нулей и единичек. А
      ещё есть восьмеричная система счисления от 0 до 7 и даже
      шестнадцатеричная от 0 до 9, а далее A, B, C, D, E, F. Последняя система
      вводила в ступор: символ «А» это же буква, а не цифра! О, сколько
      усилий пришлось приложить, чтобы мозг соотносил цифру 10 с буквой, с
      символом «А» при восприятии предложения «шестнадцатеричная цифра A» и
      т.д.

      И всех, конечно, с наступающим Новым Годом!

      Счастья и удачи, друзья! Творческих успехов!


  1. fizteh147
    30.12.2023 02:18
    -9

    Ответ на вопрос "Почему некоторые люди склонны к магическому мышлению?" можно найти в модели спиральной динамики. Люди, для которых основным уровнем является пурпурный (или фиолетовый) будут верить в магию. До тех пор, пока не разовьют в себе вышестоящие уровни.

    Рекомендую к изучению. Помогает в понимании явлений

    Поясняющий текст картинкой.

    P.S. Так что это не показатель глупости, а показатель развития человека в рамках данной модели.


  1. Arhammon
    30.12.2023 02:18
    +3

    Не понял где в примерах отсутствие логики - как раз логика очевидна. Люди не хотят чтоб система упала и им потом придется заниматься с ней любовью пока не починят. По этому, работает - не трогай.

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


    1. MAXH0
      30.12.2023 02:18
      +2

      Вот мне тоже кажется, что дело не в незнании математики и спецификаций, а в "софтах" и процесах. Процесс разработки организован так, что есть одна стабильная ветка. причем как я понимаю, большая и пронизанная зависимостями, так, что малое изменение может обрушить ВСЁ. А люди поставлены в условия, когда ответственность за обрушение кода перевешивает профит от его модификации.

      Все же понимают что так не должно быть, а "шаманизм" здесь не причем? Взять кого угодно, приставить пистолет к виску и сказать - "Меняй этот код! Будет работать, тебе ничего не будет. Не будет - сам виноват..." Готов спорить если известно, что код худо бедно работает вы внесете в код самые косметические изменения... Что собственно и произошло.


      1. Arhammon
        30.12.2023 02:18
        +1

        Если подробнее разобрать кейс то одна из проблем нежелание, неумение писать комментарии. Напиши "сделано не правильно по тому-то, почему правильно не работает хз, может ошибка в компиляторе, не разбирался - нет времени. Так тоже работает."

        Даже будучи не программистом сталкивался - пишешь на бейсике для микроконтроллера, вроде все правильно. А железяка не просыпается как положено. Копаешь документацию к баскому - все у тебя верно. Копаешь документацию к МК - все верно. Но не работает. Идешь в гугл - на 5 странице какого-то форума совет сделай все наоборот. Делаешь - все работает как часы... Ну ладно, написал комментарий на будущее и забыл, все равно у меня нет ни времени ни квалификации разбираться с компилятором.


  1. YDR
    30.12.2023 02:18
    +5

    он где-то слышал про "проблему машинного нуля", когда x+1. == x, если x>>1 или x+1.==1., если x<<1 ( "<<" соответстует тому, что 1 и x одновременно не помещаются в мантиссу представления floating poing IEEE-854(?), если привести их к одинаковой экспоненте перед сложением).

    И вот, он "слышал звон", и не знает, где он.

    Этому обычно на 1 курсе учат, что числа floating point нужно сравнивать только так:

    #define Epsilon 0.0000001

    ...

    if (fabs(x-y)<Epsilon) {...}


    1. Fedorkov
      30.12.2023 02:18
      +3

      IEEE-754.


    1. herase Автор
      30.12.2023 02:18

      Вы отличный пример того, о чём я писал. Написали фантастическую чушь и получили уже 4 лайка, причём не от девочек комсомолок, а от людей на техническом ресурсе. Никогда, слышите, никогда, не вставляйте в программы это говно! Если вам нужно сравнить два числа, просто пишите if (x == y). Арифметика чисел с плавающей запятой сама правильно проверит, равны они или нет. Ваш же говнокод будет давать результат, что один нанофарад равен одному пикофараду. Людям, расчитывающим паразитные ёмкости процессора в вашем компьютере, такой результат очень не понравится!


      1. vesper-bot
        30.12.2023 02:18
        +1

        Если вам нужно сравнить два числа, просто пишите if (x == y). Арифметика чисел с плавающей запятой сама правильно проверит, равны они или нет.

        Тут недавно был интересный трюк, когда условно 5/3 были не равны 5/3 иногда, при этом бинарно значения совпадали. Так что if x==y не всегда корректно сравнивать. А вообще сравнение чисел с плавающей запятой на равенство - отдельная дисциплина специальной олимпиады :)


      1. pudovMaxim
        30.12.2023 02:18
        +2

        Хм, заставили задуматься, но нет, не везде одинаково работает. Такой код на С:

        float a = 10.0 / 3.0 - 3.0;
        float b = 2.0 / 6.0;
        if ( a==b ) ....

        Действительно считает и сравнивает корректно. Но, например в PHP и Python вычисленные значения будут отличаться:

        0.3333333333333335
        0.3333333333333333

        А так как большинство считают циферки не для теорий и математических моделей, а для вполне практических целей, то тянуть "гавно" в виде эпсилонов и убирать избыточную точность иногда приходится.


      1. avost
        30.12.2023 02:18
        +7

        Никогда, слышите, никогда, не вставляйте в программы это говно! Если вам нужно сравнить два числа, просто пишите if (x == y). Арифметика чисел с плавающей запятой сама правильно проверит, равны они или нет

        Если нужно сравнить два числа, то да. Но обычно нужно сравнивать две величины. Заданные или расчитанные с определённой точностью.

        Ваш же говнокод будет давать результат, что один нанофарад равен одному пикофараду.

        Ну, а ваш говнокод покажет, что 5 фарад не равны 5.000000001 фарад. Формально они не равны, но кого это волнует?

        Людям, расчитывающим паразитные ёмкости процессора в вашем компьютере, такой результат очень не понравится!

        Как обращаться с погрешностями учат если не на первом, то на втором курсе любого инженерного вуза. Советую поинтересоваться. Там подробно эту проблему показывают и рассказывают.


      1. propell-ant
        30.12.2023 02:18
        +4

        Вот по ссылке статейка, где автор показывает, что оба ваши подхода неверны.

        А еще о человеке, использующем в диалогах с незнакомыми людьми слова "это го***" и "никогда, слышите, никогда" можно сказать, что он несет на себе отпечаток того коллектива, который сам же критикует в своей статье.


  1. Fedorkov
    30.12.2023 02:18
    +6

    Это не магическое мышление, это просто недостаточный опыт в программировании при большом (наверное) опыте в математике.

    Когда я рефакторю малознакомый код на десятки или сотни тысяч строк кода, у меня тоже главная задача — ничего не сломать. Даже если вижу где‑то треш, угар, содомию и рекурсивное вычисление ряда Фибоначчи, я всё это игнорирую и фокусируюсь на одном конкретном пункте рефакторинга.

    P. S. Магическое мышление — это переобученность человеческой нейронки.


    1. TheRikipm
      30.12.2023 02:18
      +1

      Это не магическое мышление, это просто недостаточный опыт в программировании при большом (наверное) опыте в математике.

      Наоборот: это достаточный опыт в программировании что бы осознать пользу принципа "Работает - не трогай".


      1. Fedorkov
        30.12.2023 02:18

        «Работает — не трогай» — это не магическое мышление.


  1. nronnie
    30.12.2023 02:18
    +3

    Сейчас все модели сломаются! Потом скажут, что мы всё сломали! Я такие изменения не пропущу!

    Долбоящеры понапишут мегатонны говнокода без единого теста, а потом годами чихнуть над ним боятся, как бы что-то не сломалось.


  1. sergeyns
    30.12.2023 02:18
    +7

    x = (a + b * c + d) * (g - sin(alpha) * cos(beta) ) * (cos(d5) + d8 + d11) / (k - t * p) / (d7 + d9 + d15);

    y = (a + b * c + d) * (g - sin(alpha) * cos(beta) ) * (cos(d5) + d8 + d11) / (k - t * p) / (d7 + d9 + d15);

    z = (a + b * c + d) * (g - sin(alpha) * cos(beta) ) * (cos(d5) + d8 + d11) / (k - t * p) / (d7 + d9 + d15);

    Не напрягая мозг я бы сказал что это какие-то проекции.. Может быть в какой-то другой "системе координат" какие-то проекции нужно считать по разному. Поэтому 3 строчки. На всякий случай, вдруг придется поменять. Иначе почему не пойти дальше: выкинуть на фиг у и z, оставить один х )))


  1. dmiche
    30.12.2023 02:18
    +4

    Вы, возможно, удивитесь, узнав, что далеко не все люди в жизни пользуются логикой. Собственно, вот обученная нейронка - она же не использует логику, она, вульгарно выражаясь, использует кейсы. Много кейсов.

    Биология человека такова, что многим людям сильную логику не раздают при рождении, зато у них, в компенсацию, кейсовое мышление развивается очень неплохо и в ситуациях, где логики не прослеживается, они будут справляться статистически сильно лучше, используя всякие мутные аналогии.

    В нашей жизни техника безопасности, правила дорожного движения и устав караульной службы - это продукты отнюдь не логики, а именно набора кейсов. Логика при их составлении была только лишь слабой отправной точкой. И именно эти кейсы спасают жизни. Но, при этом, требуют от пользователя дологического подхода - не нужно думать, нужно исполнять.

    Что касается "мистики" в коде, то, вот, в Питоне есть, например, такие фокусы:

    >>> Decimal(0.1)

    Decimal('0.1000000000000000055511151231257827021181583404541015625')

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

    В приснопамятном Борланд паскале разлива девяностых иногда добавление строчки комментария в код исправляло компиляцию. Сколько таких хвостов в NUMA-кластере, у которого пользовательская база весьма ограничена, даже подумать сложно.

    Опять же, очень часто, способный новичок, особенно, ортогональноголовый, недооценивая деталей задачи и не обладая необходимым жизненным опытом, чтобы эти детали предвидеть, полагает, что всё можно запрограммировать непротиворечиво. Смущает своими речами коллег, берётся переделывать и... стабильно увязает через 2 месяца, когда всё логичное уже сделано и мы подходим к самому интересному, обнаруживаем, например, что некорректные входные данные нельзя терять, а способов, которыми они некорректны слишком много. Если такому тимлид своевременно не настучит по голове, то это будут выкинутые трудодни.

    В общем, свежий продвинутый взгляд на код всегда полезен, но далеко не всегда бывает верен :) А с другой стороны, чистых мистиков в программировании тоже хватает. Тут, скорее, по результату нужно смотреть. Если продукт есть, если он приносит прибыль, значит модель и команда выбраны верно, что бы нам не говорило чувство перфекционизма. Когда бизнес занеможет - кто то это перепишет и сделает новый бизнес.

    P.S. А за книжечку спасибо. Хорошего Нового Года!


    1. saipr
      30.12.2023 02:18

      В приснопамятном Борланд паскале разлива девяностых иногда добавление строчки комментария в код исправляло компиляцию.

      И в Си бывало...


      1. OlegZH
        30.12.2023 02:18

        Это как?


        1. JediPhilosopher
          30.12.2023 02:18
          +3

          Да банальный баг в компиляторе наверное. Считаю, что каждый опытный программист хотя бы раз в жизни но должен его словить. Чтобы не страдать иллюзиями на тему непогрешимости своих инструментов

          Помню веселье с часами отладки в попытке понять, почему код выводит стабильно неправильные значения на простейшем куске программы (а вот что именно там надо было считать уже не помню). В итоге с привлечением мега-спеца из соседнего отдела и ковырянием в ассемблерном коде (дело было на С++) выяснилось, что это компилятор тупо генерит неправильный бинарный код для какой-то простейшей арифметической операции.

          Любое изменение структуры файла (просто перестановка местами пары методов выше по коду, даже не тех в которых была проблема) баг убирало. Баг вроде зарепортили.

          Такое тоже может быть, и не так уж и редко.


    1. OlegZH
      30.12.2023 02:18

      некорректные входные данные нельзя терять

      Что Вы имеете в виду?


      1. dmiche
        30.12.2023 02:18
        +2

        Например, нужно вкачать фио/адрес, адрес увязать с КЛАДРом. Ну и ещё ворох таких же источников и хотелок. Казалось бы, что может пойти не так, если первичку вводили живые люди?

        И вот прошаренный разработчик сразу прикинет, что заказчик захочет поиск по несовпавшим адресам и ещё какуюньть непрогнозируемую дичь. Поэтому будет планировать гибкую архитектуру, которую можно будет понятно как костылить. Ну и она закономерно обрастает этими костылями по заранее намеченной траектории.

        Потом приходит юный отличник, смотрит на вот это и начинает сердиться: "кто так строит? всё должно на всё ссылаться, нужно всё переделывать!". А поскольку это такие вещи, что если надо объяснять, то не надо объяснять, то ему один раз ответят, а дальше ждут, что он будет что-то полезное делать и живого опыта набираться.

        Конечно, бывают такие проекты, что там не спроектированный бардак, а просто бардак. Но разраб без опыта отличить не сможет.


        1. OlegZH
          30.12.2023 02:18

          Вот так, самые светлые намерения рассыпаются о суровый быт. :-(


  1. ready4wisdom
    30.12.2023 02:18
    +4

    Избыточно много ругани в адрес других людей. Есть ощущение, что автор подсознательно самоутверждается в стиле "ну бараны, ну как такое можно с высшим то образованием то, вот я бы, вот я бы, такого НИКОГДА!... ". Возможно есть какая-то книга по психологии или антропологии, где описывается механизм в психологии, когда человек переоценивая известное **лично ему начинает оценивать окружающих исключительно по этой области знаний.


    1. herase Автор
      30.12.2023 02:18
      +1

      Хабр меня спросил, одобрить Ваш комментарий или нет. Я одобрил, чтобы Вам полайкали люди, поддерживающие идею, что неправых нет, все немножко правы, и что в соревновании все немножко победители. Помните, как в фильме "Парни со стволами"? "Они вручили трофеи всем, чтобы никто не обиделся. Даже жирному тупице Роби Фридману дали." p.s. Программирование, как и точные науки, раньше отличалось от уроков литературы тем, что была чёткая грань между правыми и неправыми. Сейчас она размывается всё сильнее.


    1. herase Автор
      30.12.2023 02:18

      Обратите внимание, я сейчас ещё и страдаю за свою объективность к оппонентам)) Вам плюсуют, а мне уже кто-то заминусовал сообщение о том, что я допустил Ваш комментарий.


      1. MAXH0
        30.12.2023 02:18
        +3

        Примите Хабр таким, как он есть и перестаньте страдать! Карма тлен, а уж плюсы к комментам, так и подавно...


  1. schulzr
    30.12.2023 02:18
    +1

    Позвольте предположить, что лет через 10 уважаемый автор станет руководителем и будет отвечать за продукт и множество проектов :). И тогда ему тоже не понравятся изменения в работающем коде, только потому что его действительно умный и цепкий программист не доволен манерой автора. Уверен, что вспомнив сегодняшнюю статью, уважаемый автор найдет правильные слова, чтобы объяснить разработчикам, что просто так не стоит улучшать , что и так работает :).


    1. herase Автор
      30.12.2023 02:18
      +5

      Я вообще очень опечален, что, судя по комментариям, никто не понял, что я хотел донести. Но я отвечу на Ваш вопрос. Принцип не трогать работающий код обычно является следствием непонимания того, как что-то работает. Именно поэтому я считаю такой принцип дерьмом. Если компания работает по этому принципу, значит она движется вперёд просто по инерции. В какой-то момент количество точек непонимания превысит критическую отметку и всё посыпется как карточный домик. На том же месте работы у меня был опыт, когда доказать необходимость изменения кода логическими объяснениями того, что движок написан неправильно, ни к чему не привели. Тогда я написал модель и добавил её в список тестов. Моя прекрасная модель рушила движок просто фантастически. На каких-то машинах программа просто валилась, на каких-то намертво вешала систему. Было приятно смотреть, как все забегали. После этого необходимые изменения прошли на ура. Так что я надеюсь, что если и когда я стану руководителем, я буду слушать вменяемых людей, а не жить по принципу "давайте не раскачивать лодку".


      1. schulzr
        30.12.2023 02:18
        +1

        Я вас очень хорошо понимаю. И в любом большом куске кода найдется немало таких забавных примеров. В моем понимании это результат трудности коммуникации и спешки. Эти два фактора присутствуют в любом проекте. Плюс всегда есть история вопроса. Итого мы видим как организм из нескольких умных и талантливых людей не всегда ведёт себя рационально. И как с этим быть не всегда ясно. Бизнес задачи в приоритете, а любое изменение кода имеет ненулевую цену. Особенно если это изменение затрагивает двух человек. А не дай бог им потребуется арбитр , тогда цена легко может оказаться равна тысячам условных единиц :).


      1. rg_software
        30.12.2023 02:18
        +1

        У несчастью, мне регулярно приходится сталкиваться с кодом, который непонятно как работает, и это не вина пишущего. Такое бывает, например, если имеете дело с ворохом 3rd party зависимостей, причём требуется какая-то конкретная комбинация из версий, и везде свои баги. Эмпирически вы знаете, что такая последовательность вызовов работает, а другая - нет, причём из документации не следует ничего. Получается, что даже автор ничего вменяемого в комментариях написать не может, кроме "не трогай, должно быть так".


      1. Mingun
        30.12.2023 02:18

        Ну зато у вас появился опыт, что изменения нужно подкреплять тестами, желательно до самих изменений, чтобы было видно наглядно, что ваши изменения действительно решают проблему. Потому что ваши логические объяснения исходят из предпосылок, что все ниже вашего уровня работает правильно (условно говоря, если вы пишите деление, то в железе оно и делится, как положено. Но есть были пентиумы). А этого вы не можете знать, и комментариев нет, а судя по вашему бахвальству предположу, что и на свой супер-логичный код вы их писать не собирались (ведь логично же!). Так что правильно вас без тестов завернули. Мало ли что там кому покажется неработающим, если это до сих пор "работает" (в кавычках, потому что на самом деле ни у кого не было метрик, выполняется ли вообще этот код)


    1. nronnie
      30.12.2023 02:18
      +1

      изменения в работающем коде

      Это не работающий код, а работающий говнокод. Я вполне понимаю, что несколько присваиваний в одном выражении может не нравиться (мне оно тоже не нравится), но можно же вместо трижды копипаста строки длиной в полторы ширины экрана присвоить сначала её результат в какую-то еще одну переменную, а потом её уже присваивать по очереди в x, y, и z. Может, правда, у них какая-то особая реализация синусов и косинусов, которая имеет значимые побочные эффекты - тогда и вправду лучше не трогать (а если, все-таки, трогать, то только метров с пяти длинной палкой).


  1. UPushken
    30.12.2023 02:18

    мол если множитель равен 1, то лучше не умножать, потому что это может изменить умножаемое число, если это число мало. Писал, очевидно, человек, который не знает, что в представлении с плавающей запятой числа хранятся так, что их относительная точность не зависит от того, равно число 1.e+100 или 1.e-100.

    Знание того, как оно хранится, не поможет. Тут надо знать алгоритмы выполнения операций в плавающем формате, чтобы сделать цепочку выводов:

    • При умножении нет выравнивания порядков и связанной с этим потери точности

    • Нет потерь точности на представление единицы (как константы, а не как результата вычислений) в плавающем формате. Она хранится абсолютно точно.

    • При умножении результирующая экспонента = сумме экспонент, но у единицы она нулевая, а значит экспонента результата не изменится

    • Представление единицы имеет одни явные нули в мантиссе. Но есть одна неявная старшая единица. Именно она и гарантирует сохранение абсолютно всех знаков мантиссы другого сомножителя в старших разрядах результата. Ну а нули гарантируют обнуление всех остальных (младших) знаков мантиссы результата

    • Таким образом, мантисса результата абсолютно не изменится

    • Знак результата не изменится

    • При применении одного и того же алгоритма умножения для всех плавающих чисел, и даже при выполнении реальных вычислений, умножение на единицу никак не изменит исходное число. Даже на epsilon. Вообще ни на сколько.

    • Вот такой фокус

    Я думаю, что у программиста могла быть своя логика. Кроме того, программист мог знать вопрос досконально, но схитрил из-за оказываемого на него давления в нездоровой атмосфере.

    И это оказало некоторое воздействие на систему. Вы же сами хотя в одном месте пишете сначала это

    эта проверка является совершенно бессмысленной, хоть и довольно безвредной 

    а затем вот это

    Однако это бессмысленное изменение сделало главное: проблемная модель снова стала глючить точь-в-точь, как глючила до этого.

    Получается, что не такое уж и бессмысленное, раз оказывает влияние на поведение системы. По факту программист ловко перевел стрелки, получил премию, а потом уволился с повышением, не забыв раскрыть в резюме, как он ловко нашел и обошел глюк.