2014 dxdy logo

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

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




На страницу Пред.  1, 2, 3, 4  След.
 
 Re: Отрицательный ноль и его идентификация
Сообщение18.09.2019, 21:02 
Xaositect в сообщении #1415801 писал(а):
И у меня в коде это существенно.
У вас, очевидно, по условию аргумент неотрицательный. Вы, наоборот, доопределяете функцию в нуле, пользуясь знанием, что логарифм для eps работает осмысленно, а для нуля выдаёт минус бесконечность. Насколько это знание переносимо - вот не уверен.

 
 
 
 Re: Отрицательный ноль и его идентификация
Сообщение18.09.2019, 21:20 
Dmitriy40 в сообщении #1415800 писал(а):
Для флагов был специально NaN придуман

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

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

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

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

 
 
 
 Re: Отрицательный ноль и его идентификация
Сообщение18.09.2019, 21:54 
Аватара пользователя
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 
Munin в сообщении #1415835 писал(а):
Переносимость в мире IEEE 754 вполне может быть не столь строгой, как "переносимость вообще".
Ну, вообще проверять плавающие числа на точное равенство — обычно не лучшая идея. Вот ситуациями типа такой как у Xaositect нужда в точном равенстве наверно и исчерпывается.

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

 
 
 
 Re: Отрицательный ноль и его идентификация
Сообщение18.09.2019, 22:10 
Аватара пользователя
arseniiv в сообщении #1415839 писал(а):
Ну, вообще проверять плавающие числа на точное равенство — обычно не лучшая идея.

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

 
 
 
 Re: Отрицательный ноль и его идентификация
Сообщение18.09.2019, 22:19 
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 
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 
Andrey_Kireew
Засада в том что для очень многих целых чисел конструкция double x=-1; пишет именно что нужно, а вот для нуля - нет, исключение, double x=-0; пишет просто ноль, "положительный", и надо не забывать ставить точку в нуле.
И если эти константы раскиданы по коду тонким слоем, то второпях где-нибудь вполне вероятно забудется - и работать перестанет, и что самое плохое, не обязательно сразу.
Именно поэтому все и везде рекомендуют объявлять такие константы именованными в начале и потом везде пользоваться именами.

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

 
 
 
 Re: Отрицательный ноль и его идентификация
Сообщение18.09.2019, 22:59 
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 
Аватара пользователя
warlock66613 в сообщении #1415856 писал(а):
Вы тоже путаете undefined behavior и implementation-defined behavior.

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

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

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

 
 
 
 Re: Отрицательный ноль и его идентификация
Сообщение19.09.2019, 01:55 
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 
Аватара пользователя
warlock66613 в сообщении #1415874 писал(а):
В C (но не в С++) пока ещё можно через union, но это могут и запретить когда-нибудь.

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

-- 19.09.2019 04:14:58 --

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

 
 
 [ Сообщений: 56 ]  На страницу Пред.  1, 2, 3, 4  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group