|
1 / 1 / 0
Регистрация: 05.12.2024
Сообщений: 60
|
|
Как обнаружить потерю точности при умножении двух double14.09.2025, 12:13. Показов 5298. Ответов 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)" |
|
Нарушитель
6318 / 3043 / 1054
Регистрация: 01.06.2021
Сообщений: 11,601
|
||
| 15.09.2025, 15:55 | ||
|
Как ни крути, если что-то серьезное, все равно нужно перейти на дроби с целыми числами и все вычисления делать в целых числах.
0
|
||
|
1 / 1 / 0
Регистрация: 05.12.2024
Сообщений: 60
|
||
| 15.09.2025, 18:59 [ТС] | ||
1
|
||
|
623 / 381 / 67
Регистрация: 09.03.2016
Сообщений: 4,259
|
|
| 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
|
|||
|
Нарушитель
6318 / 3043 / 1054
Регистрация: 01.06.2021
Сообщений: 11,601
|
||
| 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
|
||
|
338 / 130 / 10
Регистрация: 19.07.2024
Сообщений: 708
|
||
| 17.09.2025, 17:34 | ||
|
Но если речь только про ПК - то да, на ПК лучше всегда использовать double. Насколько знаю - на ПК нет разницы в скорости double vs float. (Хотя тут нет полной уверености)
0
|
||
|
Нарушитель
6318 / 3043 / 1054
Регистрация: 01.06.2021
Сообщений: 11,601
|
||
| 17.09.2025, 18:00 | ||
|
0
|
||
| 17.09.2025, 18:10 | ||||
Только спокойно работать в double удается весьма редко. Тот же пример выше, луч-то не пальцем надо бросать, а либа юзает float. Тот же движок физики и др Наоборот, львиная доля людей занимается именно этим, не Вы ли работаете с Годот?Добавлено через 4 минуты
0
|
||||
|
Нарушитель
6318 / 3043 / 1054
Регистрация: 01.06.2021
Сообщений: 11,601
|
|||
| 17.09.2025, 18:13 | |||
|
Godot как раз исключение - встроенный float это 64-битный плюсовый double (годот написан на плюсах). Вот тут об этом сказано: https://docs.godotengine.org/e... float.html
0
|
|||
|
338 / 130 / 10
Регистрация: 19.07.2024
Сообщений: 708
|
||
| 17.09.2025, 19:57 | ||
|
PS: А если в приоритете точность, и скоростью вычислений можно пожертвовать, то может имеет смысл топикстартеру озаботиться созданием своего (нового) численного типа: скажем назовём его QuadFloat. 16-байтного размера. Или даже ещё бОльшего размера. С увеличенной соответственно мантиссой (а может и экспонентой). И все расчёты выполнять на нём. Ну или (как уже выше писал) - создать тип fixed point большой длины. Такой, чтобы вмещал весь диапазон чисел, необходимый в его расчётах. Это если сложно реализовать свой QuadFloat.
0
|
||
|
-72 / 65 / 2
Регистрация: 23.11.2024
Сообщений: 816
|
|
| 17.09.2025, 21:00 | |
|
0
|
|
| 17.09.2025, 21:19 | ||||
Справедливости ради, это было лет 15 назад, не исключено что сейчас уже работает.Гораздо полезнее уметь оценить погрешность/ошибку (см задачу выше), но этим заниматься никто не хочет, и понятно почему: думать надо, легко ошибиться. А вот рассказывать что 8 байт лучше чем 4 - легко и приятно
0
|
||||
|
Модератор
|
|
| 18.09.2025, 19:30 | |
|
Существуют алгоритмы, повышающие точность вычислений с плавучкой.
По большому счёту, это подобие длинной арифметики, когда за счёт дополнительной переменной увеличивается разрядность. Ну и время выполнения - тоже увеличивается. Для сложения - алгоритм Коха. Для умножения я не знаю, но, наверняка, есть. Также встречал правила изменения порядка вычислений - чтобы избежать "потерю" маленького числа на фоне значительно большего. Для этого есть множество формул преобразования и они подбираются под каждый уникальный случай.
0
|
|
|
Нарушитель
6318 / 3043 / 1054
Регистрация: 01.06.2021
Сообщений: 11,601
|
||||||||||||||||||||||||
| 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
|
||||||||||||||||||||||||
|
2469 / 1615 / 741
Регистрация: 17.03.2022
Сообщений: 5,264
|
||
| 18.09.2025, 21:18 | ||
|
Просто нормальному программисту-вычислителю попытки счета подобного "в лоб" должны разве что сниться в качестве ночных кошмаров. А если делать все нормально, то содержательных проблем не возникнет.
0
|
||
|
Нарушитель
6318 / 3043 / 1054
Регистрация: 01.06.2021
Сообщений: 11,601
|
|||
| 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) Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
| Опции темы | |
|
|
Новые блоги и статьи
|
|||
|
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С.
Задача:
Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
|
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
|
Как ИИ начал спорить и врать (возможно почуяв опасность для себя от индустрии - уход от электроники).
Hrethgir 04.08.2026
Недельный диалог, на фоне событий с НПЗ. Да, из спирта можно получать бензин, и это не сложно. Но потом в схеме я решил избавиться от насоса, при этом полностью сделав контроль подачи спирта в. . .
|
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701
Купил два термопринтера QR701.
На сэлф-тесте написано:
Language: PC936 (GB18030).
Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
|
|
Создание формы заимствованного документа
Maks 03.08.2026
Задача:
Необходимо создать собственную форму заимствованного документа. На форме должен быть реквизит "Покупатель", а также
табличная часть со следующими реквизитами:
- Расчетный счет покупателя. . .
|
Задача предоставления скидок покупателям
Maks 03.08.2026
Задача:
В документе "Продажи" необходимо реализовать функционал предоставления скидок покупателям. Скидка должна автоматически рассчитываться и подставляться в соответствующее поле при выборе. . .
|
Почему SEO не начинается с ключевых слов: что проверить до написания текстов
Neotwalker 01.08.2026
Когда владельцу сайта предлагают заняться SEO, первым шагом часто становится сбор запросов и написание текстов.
Логика кажется понятной:
1. Находим ключевые слова.
2. Добавляем их на. . .
|
Знание — сила: Доктрина интенциональности знаний, углубление в формулу
Hrethgir 01.08.2026
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11957&stc=1&d=1785567302
Знаменитый афоризм Фрэнсиса Бэкона «Знание — сила» (Scientia potentia est) в массовой культуре принято понимать. . .
|