2014 dxdy logo

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

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




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


06/10/08
6422
Я сейчас проверить не могу, но должно быть что-то типа такого:
Код:
int signbit(double x)
{
  unsigned short stw;
  __asm
  {
    fld x
    fxam
    fstsw stw
  }
  return stw & 0x0200;
}

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


20/08/14
11177
Россия, Москва
Andrey_Kireew
Я не знаю для какого компилятора был тот пример кода, Вы должны уметь легко его переделать под свой компилятор.

Xaositect
Чисто для себя я бы сделал проверку старшего бита int64 по адресу double (или int32 по адресу float), разумеется после проверки на равенство нулю. Это можно сделать даже средствами C/С++, без асм вставок, типа if((*(uint64_t*)&x)&0x8000000000000000){}.

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


07/10/15

2400
Xaositect в сообщении #1415757 писал(а):
должно быть что-то типа такого:

ругается на строчку
Код:
__asm

переднюю чёрточку пробовал убирать, начинает ругаться на фигурную скобку, наверное в VC2010 синтаксис какой то особый

-- 18.09.2019, 20:57 --

Dmitriy40 в сообщении #1415763 писал(а):
Чисто для себя я бы сделал проверку старшего бита int64

мне кажется, здесь возможны проблемы с переносимостью кода

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


02/08/11
6893
Dmitriy40 в сообщении #1415763 писал(а):
if((*(uint64_t*)&x)&0x8000000000000000){}
А так точно можно делать? В смысле, не undefined ли это behavior?

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


06/10/08
6422
Я погуглил, оказывается VS2010 не поддерживала ассеблерные вставки в 64-битном режиме. Вы под x64 компилируете, наверное? Используйте то, что Dmitriy40 написал.

-- Ср сен 18, 2019 18:07:06 --

warlock66613 в сообщении #1415778 писал(а):
А так точно можно делать? В смысле, не undefined ли это behavior?
Оно самые. Но должно работать.

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


27/08/16
9426
Dmitriy40 в сообщении #1415763 писал(а):
типа if((*(uint64_t*)&x)&0x8000000000000000){}.
Но хорошо бы написать отдельную вынесенную в хэдер функцию.

-- 18.09.2019, 20:11 --

Andrey_Kireew в сообщении #1415774 писал(а):
мне кажется, здесь возможны проблемы с переносимостью кода
Переносимому коду незачем использовать равенство плавающих чисел.

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


06/10/08
6422
realeugene в сообщении #1415783 писал(а):
Переносимому коду незачем использовать равенство плавающих чисел.
Ну это неправда, может это переносимый код какие-нибудь спецфункции релизует с разрывом в нуле.

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


20/08/14
11177
Россия, Москва
Andrey_Kireew в сообщении #1415774 писал(а):
мне кажется, здесь возможны проблемы с переносимостью кода
Мне тоже так кажется, я сразу об этом сказал.
warlock66613 в сообщении #1415778 писал(а):
Dmitriy40 в сообщении #1415763 писал(а):
if((*(uint64_t*)&x)&0x8000000000000000){}
А так точно можно делать? В смысле, не undefined ли это behavior?
Ну, я бы ещё скобочек добавил для нужного мне порядка выполнения преобразований, но в онлайн компилятор и так работает. А в остальном же преобразование типа указателя и потом битовая операция вроде бы не должны приводить к undefined behavior. Но за скобочки согласен, лучше больше: if((*((uint64_t*)(&x)))&0x8000000000000000ull){}.
realeugene в сообщении #1415783 писал(а):
Dmitriy40 в сообщении #1415763 писал(а):
типа if((*(uint64_t*)&x)&0x8000000000000000){}.
Но хорошо бы написать отдельную вынесенную в хэдер функцию.
Это думаю должен уметь делать и вопрошающий, не всё же делать за него, идея вполне видна. :mrgreen:

-- 18.09.2019, 20:19 --

На самом деле даже интересно зачем надо отличать $-0$ от $+0$ ...

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


07/10/15

2400
Xaositect в сообщении #1415780 писал(а):
Вы под x64 компилируете, наверное?

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

дело не в равенстве, отрицательный ноль используется как метка, получается очень удобно, лучше наверное и не придумать

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


06/10/08
6422
Dmitriy40 в сообщении #1415790 писал(а):
А в остальном же преобразование типа адреса и потом битовая операция вроде бы не должны приводить к undefined behavior.
Не-не, как раз преобразование типа адреса и есть undefined behaviour. Например, потому что бывают платформы, на которых разные типы имеют разные требования к выравниванию. Стандарт разрешает преобразовывать только к char * и void *. Так что вроде бы вот такое должно быть переносимым между little endian ieee754-compatible платформами.
Код:
int signbit(double x)
{
  char * data = (char *)(&x);
  return data[7]&0x80;
}

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


07/10/15

2400
Dmitriy40 в сообщении #1415763 писал(а):
if((*(uint64_t*)&x)&0x8000000000000000){}.

что же, получается это единственный более менее подходящий вариант?

-- 18.09.2019, 21:26 --

Xaositect в сообщении #1415792 писал(а):
ак что вроде бы вот такое должно быть переносимым:
Код:

int signbit(double x)
{
char * data = (char *)(&x);
return data[7]&0x80;
}


ну это мне как то больше импонирует

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


02/08/11
6893
Xaositect, вы путаете undefined behavior с implementation-specific behavior.

Xaositect в сообщении #1415792 писал(а):
Не-не, как раз преобразование типа адреса и есть undefined behaviour.
Преобразование адреса допускается по-идее (это implementation defined), а вот чтение целого числа, для которого нигде не звался конструктор - не уверен.

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


27/08/16
9426
Xaositect в сообщении #1415788 писал(а):
Ну это неправда, может это переносимый код какие-нибудь спецфункции релизует с разрывом в нуле.
Если для этого разрыва недостаточно неравенств, то идея сомнительна. Будете тщательно стараться отличать eps от нуля? Seriously?

На самом деле, "The value representation of floating-point types is implementation-defined", т. е. с переносимостью кода возникают сложности уже потому, что плавающая арифметика не обязана быть IEEE-754, не обязана поддерживать бесконечности и нечисла, и не обязана поддерживать два нуля.

-- 18.09.2019, 20:32 --

Andrey_Kireew в сообщении #1415793 писал(а):
ну это мне как то больше импонирует
С этим кодом как раз проще нарваться на непереносимость.

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


20/08/14
11177
Россия, Москва
Xaositect в сообщении #1415792 писал(а):
Dmitriy40 в сообщении #1415790 писал(а):
А в остальном же преобразование типа адреса и потом битовая операция вроде бы не должны приводить к undefined behavior.
Не-не, как раз преобразование типа адреса и есть undefined behaviour. Например, потому что бывают платформы, на которых разные типы имеют разные требования к выравниванию.
Даже для типов одинаковой длины (double и int64)? Тогда вах, понимаю. Что же, я в стандартах плаваю, так что с байтами наверное надёжнее. Хотя читая дальше вижу что возможных проблем там ещё море ...

Andrey_Kireew
Для флагов был специально NaN придуман, их можно аж $2^{52}-1$ разных. Плюс знак разумеется. $-0$ удобен лишь если он почти везде должен быть нулём, но очень-очень специальным нулём. Не стоит так делать.

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


06/10/08
6422
warlock66613 в сообщении #1415796 писал(а):
Преобразование адреса допускается по-идее (это implementation defined), а вот чтение целого числа, для которого нигде не звался конструктор - не уверен.
Да, формально я неправ, преобразовать указатель можно. Но доступ к объекту через указатель другого типа - это undefined behaviour.

-- Ср сен 18, 2019 18:35:59 --

realeugene в сообщении #1415798 писал(а):
Если для этого разрыва недостаточно неравенств, то идея сомнительна. Будете тщательно стараться отличать eps от нуля? Seriously?
Я вот буквально на прошлой неделе писал
Код:
double xlogx(double x)
{
  if (x == 0.) {
    return 0.;
  } else {
    return x * log(x);
  }
}
И у меня в коде это существенно.

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

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



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

Сейчас этот форум просматривают: Bing [bot]


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

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