|
1 / 1 / 0
Регистрация: 05.12.2024
Сообщений: 60
|
|
Как обнаружить потерю точности при умножении двух double14.09.2025, 12:13. Показов 5648. Ответов 66
Добрый день,
Пытаюсь разобраться для себя с такими интересными тонкостями вещественной арифметики, как потеря точности и переполнения. Со сложением и вычитанием ясно: если одно из чисел не равно 0, а результат равен второму - значит произошла потеря точности. Но как быть с умножением? Ведь там при потери точности произведение будет равно не одному из множителей, а просто некоему неправильному числу???
0
|
|
| 14.09.2025, 12:13 | |
|
Ответы с готовыми решениями:
66
[Error] cannot convert 'double (*)(double)' to 'double' for argument '1' to 'double pow(double, double)' Найти все двузначные числа, которые при умножении на 2 заканчиваются на 8, а при умножении на 3 - на 4. Ошибка: error LNK2001: unresolved external symbol "double __cdecl Akk(double,double,double)" |
|
Заблокирован
|
||
| 15.09.2025, 15:55 | ||
|
Как ни крути, если что-то серьезное, все равно нужно перейти на дроби с целыми числами и все вычисления делать в целых числах.
0
|
||
|
1 / 1 / 0
Регистрация: 05.12.2024
Сообщений: 60
|
||
| 15.09.2025, 18:59 [ТС] | ||
1
|
||
|
638 / 396 / 68
Регистрация: 09.03.2016
Сообщений: 4,375
|
|
| 15.09.2025, 23:12 | |
|
Если вы все пишете, что это действительно необходимо. Как нибудь... Спасибо автору конечно...
0
|
|
| 16.09.2025, 22:02 | ||
|
Рендерим 3D сцену, есть точка L, например, возможно, источник света. Из нее выбрасываем луч в направлении dir (вектор 3 флота). Луч пересекает какой-то объект в точке p. Известна нормаль N в этой точке (необязательно она нужна). Все хорошо. Теперь мы хотим как бы "ощупать лучами" окрестность точки p. Для этого генерируем напр 100 случайных точек (p1..p100) в радиусе R, для каждой вычисляем направление, напр Vec3f dir1 = (p1 - L).normallized(); Ну и бросаем лучи в этих направлениях из той же точки L. Да, но есть погрешность флота, и dir1 не будет вычислено точно, возможно при достаточно большом расстоянии между L и p в радиус R мы даже не попадем. На какой радиус мы можем рассчитывать? Все флоты 4 байта, увы, изменить это не можем
0
|
||
| 17.09.2025, 12:02 | |
|
И вот мелочь, легко забыть (и забыл). В лекции не упоминается волшебное слово/термин GPU, а сейчас так нельзя. Этот гад double не любит. И "расширенные" команды процессора (sse и все такое) - вроде там double и есть, но, судя по коду библиотек, 4-байтовые доминируют.
0
|
|
|
Супер-модератор
|
||||
| 17.09.2025, 14:40 | ||||
0
|
||||
| 17.09.2025, 16:55 | |||
Но программист не только "имеет право", но и обязан использовать все вычислительные мощности, поэтому гонорировать аспект GPU в наше время, мягко говоря, недальновидно/инфантильно- Бросаем луч из исходной точки L в точку "прицела" p1. Насколько луч отклонится от p1 за счет погрешности float? При этом исходные точки могут иметь координаты далеко не единичные. Мульены вряд ли, таких сцен избегают. А вот тыщи или даже 10 тыс - вполне. Также известно как задавалась точка прицела p1: она в плоскости с нормалью N проходящей через базовую точку p
1
|
|||
|
Заблокирован
|
||
| 17.09.2025, 17:10 | ||
|
Igor3D, при чем тут вообще GPU? Тема в разделе С++. В этом языке вычисления с числами с плавающей запятой выполняются на CPU.
Вычисления могут быть выполнены на GPU, если используется специальная библиотека или фреймворк для параллельных вычислений, например, CUDA или OpenCL, которые позволяют перенести вычисления на графический процессор. Но если мы говорим просто о С++, то все вычисления там осуществляются на CPU с использованием набора инструкций FPU (Floating Point Unit) или SSE/AVX (для векторизации - оптимизации программы с использованием векторных расширений системы команд процессора). Грубо говоря, все обычные вычисления с плавающей запятой выполняются на FPU процессора. И то, что 4-байтовый float предпочтительнее, чем double, актуально только для вычислений на GPU, поскольку всякие CUDA действительно лучше работают с 4-байтовыми числами. Однако, для современных CPU, не будет никакой разницы - float или double, особенно, если нет ограничений по памяти. Поэтому, Catstail правильно говорит, что в С++ дефолтно нужно выбирать double и не морочиться с низкой точностью float.
1
|
||
|
352 / 150 / 10
Регистрация: 19.07.2024
Сообщений: 850
|
||
| 17.09.2025, 17:34 | ||
|
Но если речь только про ПК - то да, на ПК лучше всегда использовать double. Насколько знаю - на ПК нет разницы в скорости double vs float. (Хотя тут нет полной уверености)
0
|
||
|
Заблокирован
|
||
| 17.09.2025, 18:00 | ||
|
0
|
||
| 17.09.2025, 18:10 | ||||
Только спокойно работать в double удается весьма редко. Тот же пример выше, луч-то не пальцем надо бросать, а либа юзает float. Тот же движок физики и др Наоборот, львиная доля людей занимается именно этим, не Вы ли работаете с Годот?Добавлено через 4 минуты
0
|
||||
|
Заблокирован
|
|||
| 17.09.2025, 18:13 | |||
|
Godot как раз исключение - встроенный float это 64-битный плюсовый double (годот написан на плюсах). Вот тут об этом сказано: https://docs.godotengine.org/e... float.html
0
|
|||
|
352 / 150 / 10
Регистрация: 19.07.2024
Сообщений: 850
|
||
| 17.09.2025, 19:57 | ||
|
PS: А если в приоритете точность, и скоростью вычислений можно пожертвовать, то может имеет смысл топикстартеру озаботиться созданием своего (нового) численного типа: скажем назовём его QuadFloat. 16-байтного размера. Или даже ещё бОльшего размера. С увеличенной соответственно мантиссой (а может и экспонентой). И все расчёты выполнять на нём. Ну или (как уже выше писал) - создать тип fixed point большой длины. Такой, чтобы вмещал весь диапазон чисел, необходимый в его расчётах. Это если сложно реализовать свой QuadFloat.
0
|
||
|
-196 / 65 / 2
Регистрация: 23.11.2024
Сообщений: 852
|
|
| 17.09.2025, 21:00 | |
|
0
|
|
| 17.09.2025, 21:19 | ||||
Справедливости ради, это было лет 15 назад, не исключено что сейчас уже работает.Гораздо полезнее уметь оценить погрешность/ошибку (см задачу выше), но этим заниматься никто не хочет, и понятно почему: думать надо, легко ошибиться. А вот рассказывать что 8 байт лучше чем 4 - легко и приятно
0
|
||||
|
Модератор
|
|
| 18.09.2025, 19:30 | |
|
Существуют алгоритмы, повышающие точность вычислений с плавучкой.
По большому счёту, это подобие длинной арифметики, когда за счёт дополнительной переменной увеличивается разрядность. Ну и время выполнения - тоже увеличивается. Для сложения - алгоритм Коха. Для умножения я не знаю, но, наверняка, есть. Также встречал правила изменения порядка вычислений - чтобы избежать "потерю" маленького числа на фоне значительно большего. Для этого есть множество формул преобразования и они подбираются под каждый уникальный случай.
0
|
|
|
Заблокирован
|
||||||||||||||||||||||||
| 18.09.2025, 21:09 | ||||||||||||||||||||||||
|
Даже если использовать арифметику произвольной точности, то на первый взгляд покажется, что ответ 0. Потому что всем лень что-то там оценивать. Можете сами попробовать вычислить значение данного выражения в Maxima, Maple, Mathematica. Последняя СКА хотя бы предупреждает, что не хватает машинной точности (точности для внутренних расчетов), хотя реализация n-digit точности в WM просто ломается. Ломается она и в Maple. Для тех, кто не знает, объясняю. В программах арифметики произвольной точности используется machine precision. Именно этот вид точности, например, указывается во многих СКА. machine precision это точность внутренних расчетов. Однако, в Mathematica и Maple решили пойти дальше и кроме machine precision, они реализовали еще более удобную фичу: n-digit precision - это когда ты указываешь, сколько значащих цифр должны быть корректны. n-digit precision можно использовать, например, в функции N[] или evalf. Однако, выражение выше - яркий пример того, что реализация n-digit precision данных СКА не справляется. Но даже в документации WM написано, что:
Программы просто выводят 0. У человека могут возникнуть сомнения, что ответ 0, поэтому он может попробовать увеличить машинную точность. Но даже если выбрать точность в 400 знаков, он все равно получит 0. Тут он подумает "ну значит результат и вправду 0" и тем самим совершит ошибку.
0
|
||||||||||||||||||||||||
|
2488 / 1638 / 746
Регистрация: 17.03.2022
Сообщений: 5,355
|
||
| 18.09.2025, 21:18 | ||
|
Просто нормальному программисту-вычислителю попытки счета подобного "в лоб" должны разве что сниться в качестве ночных кошмаров. А если делать все нормально, то содержательных проблем не возникнет.
0
|
||
|
Заблокирован
|
|||
| 18.09.2025, 21:25 | |||
|
на мой взгляд, как ни крути, машинную точность нужно подбирать методом тыка. Конечно, я бы хотел подать на ввод программе выражение и количестве значащих цифр, которые я хочу получить в результате, и чтобы она в ответ указала какую машинную точность мне нужно использовать в расчётах. Но как я написал выше, такую программу не создать.
0
|
|||
| 18.09.2025, 21:25 | |
|
Ошибки error C2296: -: недопустимо, левый операнд имеет тип "double (__cdecl *)(double,double,double Создать функцию с параметрами GetFunctionValue(double& a, double& b, double& c, double& x)... Реализовать в виде GetFunctionValue(double& a, double& b, double& c, double& x) Реализовать в виде GetFunctionValue(double& a, double& b, double& c, double& x) Реализовать в виде GetFunctionValue(double& a, double& b, double& c, double& x) Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version
Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
|
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер
На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
|
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/
TL DR
Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
|
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык.
Возвращает он вот это:
https:/ / i. **********/ vqBWLe2. png
Нужную строчку в 3й колонке просто выдумал. .
Это. . .
|
|
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor.
Это. . .
|
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js.
В помощники взял Яндекс-Алису.
Было создано три зала на разные интересы.
исторические и ретро
сериал Хичкок. . .
|
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
|
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#.
Название изменил на ColorStep.
Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
|