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
11867
Россия, Москва
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
7014
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
10455
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
11867
Россия, Москва
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
7014
Xaositect, вы путаете undefined behavior с implementation-specific behavior.

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

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


27/08/16
10455
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
11867
Россия, Москва
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, Супермодераторы



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

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


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

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