2014 dxdy logo

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

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




Начать новую тему Ответить на тему На страницу Пред.  1, 2, 3, 4  След.
 
 Re: Отрицательный ноль и его идентификация
Сообщение18.09.2019, 21:02 


27/08/16
9426
Xaositect в сообщении #1415801 писал(а):
И у меня в коде это существенно.
У вас, очевидно, по условию аргумент неотрицательный. Вы, наоборот, доопределяете функцию в нуле, пользуясь знанием, что логарифм для eps работает осмысленно, а для нуля выдаёт минус бесконечность. Насколько это знание переносимо - вот не уверен.

 Профиль  
                  
 
 Re: Отрицательный ноль и его идентификация
Сообщение18.09.2019, 21:20 


07/10/15

2400
Dmitriy40 в сообщении #1415800 писал(а):
Для флагов был специально NaN придуман

Я об этом наслышан, только NaN нельзя обрабатывать как 0, а "-0" можно. В этом собственно и есть удобство. Неопределённость не предполагает дальнейшей обработки, как обычного значения. У меня же такая обработка выполняется, так как "-0", это не просто метка, но одновременно и нулевое значение. Иначе, всё равно, в конце мне придётся все NaN менять на нули. Конечно можно и так, но программа запутанная получится. Тогда лучше уж завести отдельный массив с метками. Всё это можно, но вариант с "-0" мне представляется намного предпочтительнее, во всех отношениях.
Сама природа этих чисел такова, что они даже имея нулевые значения, продолжают отличаться друг от друга. Даже создатели IEEE-754 предвидели возможность появление таких чисел, и специально для этого предусмотрели два разных нуля. Введя специальную логическую тавтологию
Код:
0==-0

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

С моей стороны было бы просто оскорбительным, по отношению к разработчикам IEEE-754, не воспользоваться их разработкой, специально предназначенной для моей задачи.

 Профиль  
                  
 
 Re: Отрицательный ноль и его идентификация
Сообщение18.09.2019, 21:35 


27/08/16
9426
Andrey_Kireew в сообщении #1415818 писал(а):
С моей стороны было бы просто оскорбительным, по отношению к разработчикам IEEE-754, не воспользоваться их разработкой, специально предназначенной для моей задачи.
Они вам простят.
До C++11 не было переносимого способа узнать, плавающая арифметика реализована в соответствии с IEEE-754, или нет. Любой способ будет непереносимым. Нужно залазить на уровень представления чисел, локализуя непереносимость в отдельных специально выделенных файлах.

 Профиль  
                  
 
 Re: Отрицательный ноль и его идентификация
Сообщение18.09.2019, 21:54 
Заслуженный участник
Аватара пользователя


30/01/06
72407
warlock66613 в сообщении #1415778 писал(а):
А так точно можно делать? В смысле, не undefined ли это behavior?

Если строго придерживаться стандарта C/C++, то undefined behavior. Но если мы верим в IEEE 754, что верно почти всегда (я вспомнил, где неверно: в IBM S/390, в коде, совместимом с S/360), то нет, это вполне правильно и работает.

Вообще, низкоуровневые вещи undefined behavior ровно по модулю того, что мы не знаем конкретную аппаратуру. А если знаем, то всё окей, для того они и поддерживаются.

realeugene в сообщении #1415783 писал(а):
Переносимому коду незачем использовать равенство плавающих чисел.

Переносимость в мире IEEE 754 вполне может быть не столь строгой, как "переносимость вообще".

Xaositect в сообщении #1415792 писал(а):
Стандарт разрешает преобразовывать только к char * и void *.

Если явно произнести reinterpret_cast, то можно к чему угодно.

Andrey_Kireew в сообщении #1415791 писал(а):
отрицательный ноль используется как метка, получается очень удобно, лучше наверное и не придумать

На самом деле, это очень плохая "метка", что все и пытаются вам сообщить.

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

 Профиль  
                  
 
 Re: Отрицательный ноль и его идентификация
Сообщение18.09.2019, 22:07 
Заслуженный участник


27/04/09
28128
Munin в сообщении #1415835 писал(а):
Переносимость в мире IEEE 754 вполне может быть не столь строгой, как "переносимость вообще".
Ну, вообще проверять плавающие числа на точное равенство — обычно не лучшая идея. Вот ситуациями типа такой как у Xaositect нужда в точном равенстве наверно и исчерпывается.

Munin в сообщении #1415835 писал(а):
разочарование
Ну раз signbit известен, то может быть известен и copysign.

 Профиль  
                  
 
 Re: Отрицательный ноль и его идентификация
Сообщение18.09.2019, 22:10 
Заслуженный участник
Аватара пользователя


30/01/06
72407
arseniiv в сообщении #1415839 писал(а):
Ну, вообще проверять плавающие числа на точное равенство — обычно не лучшая идея.

Если мы к ним относимся как к числам. Но вот Andrey_Kireew к ним ещё относится и как к "меткам" каким-то. Ещё можно к ним относиться как к хранимым данным, например, к эталонным данным в файле. Искать несовпадения, считать контрольные суммы, и так далее.

 Профиль  
                  
 
 Re: Отрицательный ноль и его идентификация
Сообщение18.09.2019, 22:19 
Заслуженный участник


20/08/14
11060
Россия, Москва
Xaositect в сообщении #1415757 писал(а):
Я сейчас проверить не могу, но должно быть что-то типа такого:
Код:
int signbit(double x)
{
  unsigned short stw;
  __asm
  {
    fld x
    fxam
    fstsw stw
  }
  return stw & 0x0200;
}
Хочу тут добавить, под x64 соглашение о вызовах подразумевает передачу плавающих типов в xmm0 (вот и пример онлайн компилятора в ассемблерный текст), так что придётся где-то выделить память (удобно на стеке, можно даже совместить с stw хотя это и плохая практика), сохранить туда xmm0 и лишь потом читать в FPU. Хотя проще будет код как раз из того примера:
Используется синтаксис ASM
movq rax,xmm0
shr  rax,63
ret

 Профиль  
                  
 
 Re: Отрицательный ноль и его идентификация
Сообщение18.09.2019, 22:22 


07/10/15

2400
Munin в сообщении #1415835 писал(а):
то у вас и будет создано число "отрицательный ноль", и например, оно будет записано в переменную. Вот тут вас ждёт жестокий облом разочарование

С чего бы это вдруг? По крайней мере, пока ничего такого ни разу не наблюдал. Создаются эти числа как раз без проблем. В чём подводные камни?

-- 18.09.2019, 23:24 --

пишем:
Используется синтаксис C++
double x=-0.0;

и всё, отрицательный ноль готов.

-- 18.09.2019, 23:31 --

Munin в сообщении #1415842 писал(а):
Искать несовпадения, считать контрольные суммы, и так далее

Да, всё это можно, и порою даже не просто можно, но даже необходимо бывает сделать.

 Профиль  
                  
 
 Re: Отрицательный ноль и его идентификация
Сообщение18.09.2019, 22:35 
Заслуженный участник


20/08/14
11060
Россия, Москва
Andrey_Kireew
Засада в том что для очень многих целых чисел конструкция double x=-1; пишет именно что нужно, а вот для нуля - нет, исключение, double x=-0; пишет просто ноль, "положительный", и надо не забывать ставить точку в нуле.
И если эти константы раскиданы по коду тонким слоем, то второпях где-нибудь вполне вероятно забудется - и работать перестанет, и что самое плохое, не обязательно сразу.
Именно поэтому все и везде рекомендуют объявлять такие константы именованными в начале и потом везде пользоваться именами.

 Профиль  
                  
 
 Re: Отрицательный ноль и его идентификация
Сообщение18.09.2019, 22:53 


07/10/15

2400
Я понял этот нюанс, видимо "-0" он воспринимает как целое, среди которых "-0" не предусмотрен, и знак просто игнорирует. А уже потом, преобразует число в double, при этом знак разумеется теряется. Но при использовании записи "-0.0" такое невозможно. Вообще, я стараюсь в double всегда ставить точку с нулём, из тех соображений, что хуже от этого уж точно не станет. Теперь, выясняется, что это помогает избежать недоразумений.

 Профиль  
                  
 
 Re: Отрицательный ноль и его идентификация
Сообщение18.09.2019, 22:59 
Заслуженный участник


02/08/11
6874
Munin в сообщении #1415835 писал(а):
Вообще, низкоуровневые вещи undefined behavior ровно по модулю того, что мы не знаем конкретную аппаратуру. А если знаем, то всё окей, для того они и поддерживаются.
Вы тоже путаете undefined behavior и implementation-defined behavior. Undefined behavior - это такой код, наличие которого в программе снимает с компилятора любые гарантии относительно поведения скомпилированной программы. То есть поведение скомпилированной программы, содержащей undefined behavior, абсолютно непредсказуемо.

-- 19.09.2019, 00:12 --

Munin в сообщении #1415835 писал(а):
Если явно произнести reinterpret_cast, то можно к чему угодно.
Преобразовывать можно, и гарантируется, что обратное преобразование даст исходное значение, но разименовывать получившийся указатель нельзя, кроме, как правильно сказал Xaositect, char * и void * (ну и ещё std::byte *): reinterpret_cast conversion.

-- 19.09.2019, 00:48 --

Если кому интересен законный способ, вот: bit_cast

 Профиль  
                  
 
 Re: Отрицательный ноль и его идентификация
Сообщение19.09.2019, 01:39 
Заслуженный участник
Аватара пользователя


30/01/06
72407
warlock66613 в сообщении #1415856 писал(а):
Вы тоже путаете undefined behavior и implementation-defined behavior.

Да, на этот нюанс не обратил внимания. Но то, что я написал, в силе. Даже UD, если вы знаете, что делаете, безопасно. А в данном случае указатель на невыровненное число не получится.

Правда, я как-то потерял нить, вообще зачем с указателями играться. Ведь reinterpret_cast позволяет оборотить дабл в уинт64 напрямую, разве нет? Или он до сих пор отсутствует в pure C?

 Профиль  
                  
 
 Re: Отрицательный ноль и его идентификация
Сообщение19.09.2019, 01:55 
Заслуженный участник


02/08/11
6874
Munin в сообщении #1415871 писал(а):
едь reinterpret_cast позволяет оборотить дабл в уинт64 напрямую, разве нет?
Нет. memcpy - практически единственный рабочий способ. В C (но не в С++) пока ещё можно через union, но это могут и запретить когда-нибудь.
Munin в сообщении #1415871 писал(а):
Или он до сих пор отсутствует в pure C?
Он всегда будет отсутствовать в pure C, ибо он - пусть и встроенная - но всё же шаблонная функция.

 Профиль  
                  
 
 Re: Отрицательный ноль и его идентификация
Сообщение19.09.2019, 01:55 


27/08/16
9426
Munin в сообщении #1415871 писал(а):
Ведь reinterpret_cast позволяет оборотить дабл в уинт64 напрямую, разве нет?
Не было нужды проверять, но думаю, что нет:

Цитата:
Conversions that can be performed explicitly using reinterpret_cast are listed below. No other conversion can be performed explicitly using reinterpret_cast.


И в списке нет плавающих чисел.

-- 19.09.2019, 02:24 --

realeugene в сообщении #1415811 писал(а):
для eps

Речь должна идти не про eps, а про 4.9e-324 для стандартных 64-битных плавающих.

 Профиль  
                  
 
 Re: Отрицательный ноль и его идентификация
Сообщение19.09.2019, 04:14 
Заслуженный участник
Аватара пользователя


30/01/06
72407
warlock66613 в сообщении #1415874 писал(а):
В C (но не в С++) пока ещё можно через union, но это могут и запретить когда-нибудь.

Как это могут запретить? C не может потерять своей низкоуровневости.

-- 19.09.2019 04:14:58 --

warlock66613, realeugene
Насчёт r.c. убедили.

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

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



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

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


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

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