2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2, 3, 4, 5, 6  След.
 
 Re: Метод половинного деления
Сообщение19.07.2020, 14:55 
Заслуженный участник


27/04/09
28128
В цифровой обработке звука в реальном времени (если используются флоуты) даже иногда подмешивают слабый неслышимый шум нормализованных чисел, чтобы денормализованные появлялись реже например в конце хвостов семплов, или там особенно в сигнале, где много и тишины, и звука, после хорошенькой такой реверберации.

 Профиль  
                  
 
 Re: Метод половинного деления
Сообщение19.07.2020, 15:06 
Заслуженный участник
Аватара пользователя


22/06/12
2129
/dev/zero
Dmitriy40 в сообщении #1474501 писал(а):
Нередко может быть важно точно $0$ получился или нет.

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

(Оффтоп)

Я просто тему прочитал, увидел, что вы упомянули денормали $n > 1$ раз, и никто не решился обсудить вопрос.


С другой стороны деятельность человека вся состоит из решения плохих задач, конечно :roll:

Dmitriy40 в сообщении #1474501 писал(а):
Наткнуться же на денормализованные числа можно почти в любом месте вычислений, не проверять же результат каждой операции (можно, но ведь тормоза же, да и код пухнет) ...

Насколько я знаю, в режиме -ffast-math, например, денормали сразу в ноль превращаются. Помню я один пример, когда товарищ с выпученными глазами спрашивает, почему на одной конкретной функции интеграл считается в 30!!! раз дольше, чем на всех остальных функциях, и проблема там была в том, что как раз программа мусолила денормализованные числа.

Ведь у нас double это же всегда компромисс между скоростью и точностью в известном смысле. И в известном же смысле денормализованный режим -- это потеря и того, и другого. В топку их!! :-)

 Профиль  
                  
 
 Re: Метод половинного деления
Сообщение19.07.2020, 16:16 
Заслуженный участник


27/04/09
28128
IEEE 754 даже без денормализованных — тот ещё компромисс, вон ±0 например… :roll: Но о Диэдр насколько же удовлетворительный!

Пока.

(Оффтоп)

StaticZero в сообщении #1474514 писал(а):
С другой стороны деятельность человека вся состоит из решения плохих задач, конечно :roll:
У меня вот есть наивная вера, что на самом деле все задачи, которые стоит решать, формулируемы адекватно при желании, просто может быть чуть длиннее, чуть в более хитрых терминах, и с более явно указанной природой того, в чём всё варится. (А поиски чего-то, что ещё не очень ясно, не будем представлять как набор решений вполне определённых задач, так что половина плохих задач просто исчезнет. Если вдруг есть желающие так делать, потому что такое представление странно и не соответствует действительности.)

 Профиль  
                  
 
 Re: Метод половинного деления
Сообщение19.07.2020, 17:57 
Заслуженный участник


20/08/14
11172
Россия, Москва
StaticZero
Засада в том что не всегда можно заранее выявить получатся ли в вычислениях денормализованные числа (если б да, то можно обойти алгоритмически). И тогда уж лучше в 30 раз дольше, но хоть сколько-то похоже на правильный результат, чем гарантированная ошибка. А при усечении к нулю появляются артефакты (типа нарушения законов арифметики), которые могут вылезти в совсем неожиданном месте, и если можно их хоть немного отложить (за счёт потери скорости обработки и точности денормализованных чисел), то это полезно. Они, артефакты, конечно всё равно когда-нибудь вылезут, но чем дальше/позже, тем лучше для программиста.

(Оффтоп)

Кстати, почему денормализованные до сих пор тормозят мне лично непонятно, сейчас кристаллы настолько огромные, что добавить в них второй нормализватор результата для быстрой и корректной обработки денормализованных чисел не проблема. Совершенно. Видимо просто никому скорость работы с ними и не нужна.
У меня впечатление что уже лет 10-15 как скорость работы АЛУ центрального процессора перестала всех волновать, как дошли до такта на почти все команды, так и забили на дальнейшее ускорение, переключились на мнопоточность/многоядерность (включая и всякие SSE/AVX) и GPU. По моему сложность AVX уже практически достигла сложности VLIW и единственным (правда очень сильным) преимуществом остаётся что очень неплохой планировщик выполнен аппаратно, чего в VLIW нормально решить (переложить его функции на компилятор) так и не смогли (кроме как в DSP), частично по объективным причинам.

arseniiv
Стандарт писался фактически "по живому" 8087, так что там немало спорных решений (я бы даже сказал что микросхему делали инженеры как могли и как им казалось логичнее, а через много лет математики попытались их детище стандартизировать, хотя конечно всё было сложнее).
А вот $\pm 0$ мне наоборот нравится, я бы возможно даже ещё размножил нули, до трёх штук, $-0; 0; +0$ — чтобы первый и последний были не нулём, а неким неизвестным числом строго меньше/больше нуля, именно ради надёжного установления точного равенства нулю. Но видимо пользы от этого достаточно мало, а сделать очевидно трудно/сложно, тем более в те годы, так что вах.

 Профиль  
                  
 
 Re: IEEE 754
Сообщение19.07.2020, 19:53 
Заслуженный участник
Аватара пользователя


22/06/12
2129
/dev/zero
Dmitriy40 в сообщении #1474547 писал(а):
Засада в том что не всегда можно заранее выявить получатся ли в вычислениях денормализованные числа (если б да, то можно обойти алгоритмически)

Проблематика отключения денормалей популярная, на самом деле.

Dmitriy40 в сообщении #1474547 писал(а):
А при усечении к нулю появляются артефакты (типа нарушения законов арифметики), которые могут вылезти в совсем неожиданном месте, и если можно их хоть немного отложить (за счёт потери скорости обработки и точности денормализованных чисел), то это полезно. Они, артефакты, конечно всё равно когда-нибудь вылезут, но чем дальше/позже, тем лучше для программиста.

Как я понимаю вас, вы намекаете на код, который "умрёт", когда получить чистый ноль на каком-то этапе (перестанет давать надёжные результаты). А я вот сомневаюсь, что код, который так себя ведёт с чистым нулём, будет давать хороший результат и с денормализованными числами тоже. Как правило, там где-нибудь сидит потеря точности, причём by design.

 Профиль  
                  
 
 Re: IEEE 754
Сообщение19.07.2020, 20:03 
Заслуженный участник


12/07/07
4448
Dmitriy40 в сообщении #1474547 писал(а):
я бы возможно даже ещё размножил нули, до трёх штук, $-0; 0; +0$ — чтобы первый и последний были не нулём, а неким неизвестным числом строго меньше/больше нуля, именно ради надёжного установления точного равенства нулю.
Я так понимаю, что утверждается, что два числа с плавающей точкой (одинарной или двойной точности) могут быть не равны, но их разность будет равна нулю. Разность может стать равной нулю, если она меньше минимального денормализованного. Пусть у нас два положительных числа двойной точности (нормализованных) 1.0…01 E0 и 1.0…00 E0 — минимальное и ближайшее к нему минимальное. Разность будет как раз минимальным денормализованным. Вроде всё работает? А разность близких денормализованных, это конечно ноль, но уже до того нас предупредили прерыванием (FPU) о возникновении денормализованного операнда и мы можем проявлять особую бдительность. [О разности денормализованных — это глупость, см. ниже. ]. Я что-то пропустил?
А где нужно сравнивать именно разность с нулём? (Практические важные примеры?)

 Профиль  
                  
 
 Re: IEEE 754
Сообщение19.07.2020, 20:28 
Заслуженный участник


27/04/09
28128
Dmitriy40 в сообщении #1474547 писал(а):
Кстати, почему денормализованные до сих пор тормозят мне лично непонятно
Так вроде и не везде. Но если всё-таки с ними до сих пор плохо, то может быть из-за их положения в мире выходит не сильно экономически оправданным тратиться на проектирование дополнительных блоков, когда и так большей частью работает? (В общем правило 80—20.)

Dmitriy40 в сообщении #1474547 писал(а):
Стандарт писался фактически "по живому" 8087
Да, про это тоже наслышан.

Dmitriy40 в сообщении #1474547 писал(а):
А вот $\pm 0$ мне наоборот нравится, я бы возможно даже ещё размножил нули, до трёх штук, $-0; 0; +0$ — чтобы первый и последний были не нулём, а неким неизвестным числом строго меньше/больше нуля, именно ради надёжного установления точного равенства нулю.
Да, мне больше не нравится то, что с этими нулями творится именно по стандарту. Так-то польза от них есть, например кстати позавчера наткнулся на такую штуку (это часть обсуждений, которые велись при разработке Common Lisp). Если бы нулей сделать три и более разумно определить для них операции, с ними можно было бы делать штуки, а текущая ситуация вызвала внезапно отсутствие не сильно нужной, но иногда всё же нужной, функции знака числа в Python (осторожно, среди ответов и комментариев есть и глупости). Но на один ноль вместо двух в некотором будущем стандарте больше надежды, чем на три.

 Профиль  
                  
 
 Re: IEEE 754
Сообщение19.07.2020, 23:02 
Заслуженный участник


20/08/14
11172
Россия, Москва
GAA в сообщении #1474613 писал(а):
Я что-то пропустил?
Кроме разности есть ещё операция деления, в результате которой сейчас может получиться точно ноль при ненулевом числителе. В ситуации с тремя нулями получилось бы строго положительное число (правда неизвестное). Не уверен, но наверное такое может возникнуть при нормализации векторов/матриц (в графике к примеру), при этом матрица может приобрести или потерять некие специфичные свойства (да ту же диагональность). Но фантазирую пишу из головы, могу и ошибиться.
Вообще Ваш пример с конкретными числами замечательно иллюстрирует причину введения денормализованных чисел: чтобы при вычитании разных нормализованных точно ноль не получался. Всё же вычитание и сравнение с нулём достаточно распространены (как минимум были, в те времена, многочисленные исследования погрешностей и надёжности вычислений появились спустя пару десятков лет только, как мне помнится).
GAA в сообщении #1474613 писал(а):
А где нужно сравнивать именно разность с нулём? (Практические важные примеры?)
Опять же из головы (сам практически не занимался этими темами): решение уравнений; определение сонаправленности векторов. Если не именно разность с нулём, то нормализация вектора (при возведении в квадрат можем получить ноль вместо малого положительного числа, что эквивалентно повороту вектора), да и вообще много операций где вычисляется длина вектора. Много где. Вопрос правда насколько везде там это значимо и нельзя ли везде предусмотреть проверку или обходной путь (и сколько это будет стоить, программисту и в runtime).

StaticZero в сообщении #1474610 писал(а):
Как я понимаю вас, вы намекаете на код, который "умрёт", когда получить чистый ноль на каком-то этапе (перестанет давать надёжные результаты).
Не то чтобы умрёт, но ошибка замены положительного числа нулём может поползти дальше и результат может получиться совершенно неверным (например слышал про проблему устойчивости численных решений систем уравнений, а если они ещё и нелинейные ...).

arseniiv в сообщении #1474621 писал(а):
может быть из-за их положения в мире выходит не сильно экономически оправданным тратиться на проектирование дополнительных блоков, когда и так большей частью работает?
Ну видимо да. Хотя и могли бы при очередной переделке FPU блоков и это доделать, не так уж это сложно (а места на кристалле вообще займёт слёзы).

 Профиль  
                  
 
 Re: IEEE 754
Сообщение20.07.2020, 22:28 
Заслуженный участник


18/01/15
3103
GAA в сообщении #1474613 писал(а):
А разность близких денормализованных, это конечно ноль

:shock: Думаю, Вы ошибаетесь. Насколько я понимаю, в IEEE-754 разность двух разных чисел --- всегда не ноль (в т.ч. денормализованных).

 Профиль  
                  
 
 Re: IEEE 754
Сообщение20.07.2020, 23:14 
Заслуженный участник


12/07/07
4448
Да, конечно, разность будет не нулевой. Глупость написал. Спасибо, vpb.

По поводу деления или умножения с получением нуля. При делении ненулевого числа на большое число в регистре может получиться 0 (соответствующего знака), но при этом, на примере FPU x87 для конкретности, флаг UE (Underflow Error) STW будет поднят и дальше можно будет выполнить нужную обработку. Регистры FPU 80-бит. Событие UE может возникнуть и при сохранении в переменную, имеющую меньший размер, например в Double. И тоже будет поднят флаг UE. Решаемо, но требует аккуратности.

-- Mon 20.07.2020 22:22:37 --

А вот с введением трех нулей (или с введением одного нуля) ранее написанные программы могут не работать. На мой взгляд, «точный ноль» дело исключительное. Проще считать, что +0 — это точный ноль и малое положительное, которое к нему округлилось. А -0 — это малое отрицательное, которое к нулю округляется. Возможности для полного контроля вычислений есть, но да (вспоминая прошлое) — очень занудно (громоздко) писать.

 i  Ветки на одну тему соединены.

 Профиль  
                  
 
 Как происходит округление в арифметике с плавающей точкой?
Сообщение25.09.2020, 11:12 


01/03/20
46
В книге Форсайт машинные методы мат. вычислений:

Изображение

Изображение

А как сейчас по стандарту IEEE754 происходит округление результата арифметической операции, если он находится ровно посередине: до большего, до меньшего или более сложные правила?

 Профиль  
                  
 
 Re: Как происходит округление в арифметике с плавающей точкой?
Сообщение25.09.2020, 11:52 
Заслуженный участник


26/05/14
981
Цитата:
Round to nearest, ties to even – rounds to the nearest value; if the number falls midway, it is rounded to the nearest value with an even least significant digit; this is the default for binary floating point and the recommended default for decimal.

https://en.wikipedia.org/wiki/IEEE_754#Rounding_rules

 Профиль  
                  
 
 Re: Как происходит округление в арифметике с плавающей точкой?
Сообщение25.09.2020, 12:35 
Заслуженный участник


12/07/07
4448
[Вольный перевод с английского]

Имеется четыре основных «режима» округления (в скобках указаны атрибуты в соответствии с IEEE-754):
1) «к большему» (roundTowardPositive): округление в сторону ($+\infty$);
2) «к меньшему» (roundTowardNegative): округление в сторону ($-\infty$);
3) «к нулю» (roundTowardZero) округление в сторону нуля;
4) «к ближайшему» (Rounding to nearest);

[Первые три описаны в разделе “Directed rounding attributes” стандарта, четвертый в разделе “Rounding-direction attributes to nearest”.]

Округление «к ближайшему» имеет два варианта: округление к четному (roundTiesToEven) и округление к большему (roundTiesToAway).

В случае округления к четному, если округляемое число находится посередине между двумя ближайшими значениями приёмника, то оно округляется так, чтобы последн[ий бит]яя оставляемая цифра приёмника оказался чётным (гауссово округление, так обычно учат округлять геодезистов).
В случае округления к большему, если округляемое число находится посередине между двумя ближайшими значениями приёмника, то оно округляется так, что последний бит последняя цифра в приёмнике увеличивается на 1 (так обычно учат округлять в «общеобразовательной школе»).

Всякая реализация стандарта должна поддерживать все четыре режима округления. В случае округления «к ближайшему» обязано быть реализовано округление к четному (roundTiesToEven), а округление «к большему» (roundTiesToAway) — не обязано. Округление «к четному» должно быть округлением по умолчание для бинарных форматов. В случае «десятичных форматов» режим округления по умолчанию зависит от языка, но рекомендуется {should be} roundTiesToEven.

Редакция IEEE-754-2019 в этой части ничего не меняет по сравнению с редакцией IEEE-754-2008.

Редактирование: «последний бит» исправлен на «последняя оставляемая цифра»

 Профиль  
                  
 
 Re: Как происходит округление в арифметике с плавающей точкой?
Сообщение25.09.2020, 15:27 


01/03/20
46
GAA в сообщении #1484560 писал(а):
Имеется четыре основных «режима» округления
А какой из них используется, например при работе программы на C++? От чего это зависит и на каком уровне регулируется?

 Профиль  
                  
 
 Re: IEEE754
Сообщение25.09.2020, 16:24 
Заслуженный участник


12/07/07
4448
round — использует режим округления по умолчанию (roundTiesToEven), если конечно не изменил программист явно (см. дальше).
ceil («потолок»)— к $+\infty$ (roundTowardPositive).
floor («пол») — к $-\infty$ (roundTowardNegative).
trunc («усечение») — к нулю (roundTowardZero). [При FPU-ориентированном коде для более-менее современных процессоров функцию trunc стараются реализовать при помощи инструкции fisttp.]

При FPU-ориентированном коде инструкции выполняются в соответствии с режимом округления заданном в регистре состояния управления FPU. В большинстве реализаций компиляторов разработчики стараются реализовать следующую дисциплину. Режим по умолчанию —«округление к чётному» (в регистре состояния управления почти всё время задано округление к четному). Если для выполнения действий нужно использовать другой режим округления, то изменяется режим округления, а после выполненных действий восстанавливается режим округления «к четному».

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

Embarcadero / Borland Delphi / TP / C++ / C — это функция Set8087CW. [Ес-но после выполнения нужных действий нужно восстановить режим по умолчанию. Иначе некоторые функции могут работать неверно.]

При SSE/AVX-ориентированном коде — аналогично.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 80 ]  На страницу Пред.  1, 2, 3, 4, 5, 6  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group