Russian Qt Forum
Апрель 19, 2024, 19:53 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 ... 3 4 [5]   Вниз
  Печать  
Автор Тема: Старая шутка  (Прочитано 37484 раз)
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #60 : Февраль 26, 2017, 15:24 »

Скажу более конкретно:
!(w>=0) - это НЕ проверка на Nan, а лишь желание положиться на определенное поведение компилятора (которому он совершенно не обязан следовать), причем абсолютно не переносимое. Чем это лучше того, что человек вообще не проверит входные данные?
Поэтому говно, однозначно.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #61 : Февраль 26, 2017, 16:51 »

Ах как Вы взыскательны Улыбающийся Однако практически бесконечные проверки Вас быстро вымотают и засорят код. Тогда броситесь в др крайность - ничего не проверять. И.т.д. В общем вариант с проверкой nan отнюдь не плох.

На мою взыскательность можно забить Улыбающийся, но вычисления прежде всего должны быть корректными, с погрешностью допустимой для поставленной задачи, а не быстрыми и простыми в написании. Полагаясь, что функции в большом выражении могут возвращать NaN, и тогда всё выражение будет равно NaN, можно получить облом. В том же mingw 5.4.0 выражение "sin( sqrt( -3.14 ) )" вполне себе вычисляется и возвращает значение "-0.00159265", которое выглядит вполне нормальным и не NaN.
Записан

Пока сам не сделаешь...
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #62 : Февраль 27, 2017, 09:02 »

В том же mingw 5.4.0 выражение "sin( sqrt( -3.14 ) )" вполне себе вычисляется и возвращает значение "-0.00159265", которое выглядит вполне нормальным и не NaN.
Ну что же Вы аргументируете багами конкретного компилятора? Некорректно

Что касается альтернативы
Код
C++ (Qt)
errno = 0;
float b = sqrt(a);
if (errno == EDOM) ...
Что-то мне совсем не хочется так делать в рабочем коде. Это надо "окружать", разбираться (а вдруг не EDOM а что-то другое?), да и парочка вызовов errno что-то потянет в число-дробилке. В общем, обычная "рекомендация для других", сам рекомендующий вряд ли будет ей следовать Улыбающийся

Скажу более конкретно:
!(w>=0) - это НЕ проверка на Nan, а лишь желание положиться на определенное поведение компилятора (которому он совершенно не обязан следовать), причем абсолютно не переносимое. Чем это лучше того, что человек вообще не проверит входные данные?
Поэтому говно, однозначно.
"совершенно", "абсолютно" - никогда не верьте таким "превосходным степеням", это банальная попытка "взять на понт" - и ничего более Улыбающийся Пользуюсь этим приемом со времен CodeWarrior, сколько компиляторов за это время сменил - не считал, ну может десяток. Пока проблем не было. Да и чего это я не должен верить справочнику
Цитировать
If the implementation supports IEEE floating-point arithmetic (IEC 60559),
    If the argument is less than -0, FE_INVALID is raised and NaN is returned.
Ах, возможно я буду работать на платформе где не поддерживается IEC 60559!! Ну если доживу до этого - тогда и буду разбираться  Улыбающийся
« Последнее редактирование: Февраль 27, 2017, 09:07 от Igors » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #63 : Февраль 27, 2017, 09:30 »

Что-то мне совсем не хочется так делать в рабочем коде.
Поэтому и нужно проверять аргументы функции до ее вызова, чтобы не поймать на выходе NaN.
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #64 : Февраль 27, 2017, 14:46 »

В том же mingw 5.4.0 выражение "sin( sqrt( -3.14 ) )" вполне себе вычисляется и возвращает значение "-0.00159265", которое выглядит вполне нормальным и не NaN.
Ну что же Вы аргументируете багами конкретного компилятора? Некорректно

Я поэтому и спрашивал, баг это или фича Улыбающийся. Похоже на баг и дальнейшие расследования привели сюда: sqrt() no longer returns NaN for x less than -0, история изменений sqrt.def.h. Больше всего интересен Commit [6617eb] и мотивы, по которым поломали поведение по справочнику:
Цитировать
The R language has some hacks specifically for mingw-w64 that were caused by our handling of NaNs in sqrt(x). R uses a special valued NaN to mean 'Not Available' and expects it to be retained through various calculations. Our sqrt(x) doesn't do this, instead it normalises such a NaN (retaining sign).

Т.е. NaN'ы разные бывают Улыбающийся. Кому-то нужен "special valued NaN", но sqrt обрезает до "обычного NaN", и чтобы что-то работало, нужно "some hacks specifically for ..." Веселый.

Заодно можно посмотреть как проверяют входные данные. Если предположить, что разработчики компилятора лучше знают внутреннюю кухню с float, NaN и прочим, то почему они пишут долго и муторно:
Код
C++ (Qt)
int x_class = fpclassify (x);
if (x_class == FP_NAN || signbit (x))
{ ... }
а не быстро и эффективно:
Код
C++ (Qt)
if (!(x>=0))
{ ... }
Записан

Пока сам не сделаешь...
Страниц: 1 ... 3 4 [5]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.196 секунд. Запросов: 23.