zHz00 Untitled

четверг, 13 марта 2025
04:37 Точность -- вежливость компьютера
У меня было выражение вида A*B-C*D. Было подозрение, что оно считается неправильно. Приблизительные значения были:

A=1997
B=1.28e13
C=4.61e8
D=5.57e7

И расчёты на калькуляторе давали -1.1e14. А расчёты в программе давали в тысячу (!) раз меньше. Это было совершенно непонятно. Я заподозрил отладчик в ошибочном отображении (что уже бывало), но схватить его за руку так и не смог. Не нравилось мне вычитание, т.к. при вычитании больших чисел погрешности получаются тоже большие. В целях отладки я сделал две отдельные переменные, A*B и C*D, и решил посмотреть, что там.

Тут-то всё и выяснилось. Расчёты на калькуляторе показывали 2.556e16 и 2.567e16 (разница в 3-й значащей цифре), а расчёт на компьютере 2.568610e16 и 2.568595e16 (разница в пятой значащей цифре). Разность первых двух чисел составила -1.1e14, а вторых всего 1.5e11 (ещё и знак другой).

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


@темы: Фейлы, Борьба с техникой

URL
Одно это чего стоит :) Current music: Андрей Макарев...
Мир полон незаметной магии. Кругом удивительное число ...
Ко всему прочему проходят тут сейчас еше и выборные компа...
Что б вам такого написать?:) ХОРОШЕГО?:) Сегодня мне в...
Еду :о))Счастья полные штаны[изображение]. В этом году пе...
дарственная надпись на книге:"Катюш,найдешь смысл - ...

13.03.2025 в 04:59

13.03.2025 в 04:59
Мы передаем позицию, куда нужно сдвинуть текущую ось, в motion controller. И иногда у нас команда не отрабатывала, а контроллер возвращал какой-то непонятный эксепшон. В итоге выяснилось, что иногда наш float становился таким маленьким, что при конверсии в string записывался в условном виде "1.23e-5". А контроллер такой записи не понимает.

Пришлось принудительно наш float умножать на 1000, конвертить к инту, а затем умножать на 0.001f.
Ошибка ушла.
URL

13.03.2025 в 09:33

13.03.2025 в 09:33
Foul thing, это в каком языке такие приколы? Мне на ум сразу приходит идея применить стандартный sprintf вместо костылей с умножением.
URL

13.03.2025 в 12:59

13.03.2025 в 12:59
Foul thing, Xersareeth, дааа, старый добрый sprintf даёт предсказуемые результаты. Я опечален, что в новом стандарте си++ добавили библиотеку форматного вывода питоновского стандарта, а не си-шного.
URL

14.03.2025 в 00:53

14.03.2025 в 00:53
Это C# с передачей данных на 3rd party контроллер.
URL
Добавить комментарий

Расширенная форма

Подписаться на новые комментарии
Получать уведомления о новых комментариях на E-mail