Да, есть обработчик событий ondrag()
, который срабатывает во время перетаскивания элемента. Если вы хотите вызвать функцию в самом начале действия перетаскивания, есть также обработчик событий ondragstart()
.
Если вы хотите захватить, когда элемент перетаскивается поверх элемента (но не отброшен), есть ondragenter()
, который срабатывает один раз, как элемент перетаскивается в элемент, а также ondragover()
, который срабатывает многократно, когда элемент перетаскивается поверх элемента. 1112]
Согласно стандарту IEEE, значения NaN имеют нечетное свойство, что сравнения, вовлекающие их, всегда ложь. Таким образом, для плавания f, f != f
будет верен только , если f будет NaN.
Примечание, что, как некоторые комментарии ниже указали, не, все компиляторы уважают это при оптимизации кода.
Для любого компилятора, который утверждает, что использовал плавающую точку IEEE, этот прием должен работа. Но я не могу гарантировать, что это будет работа на практике. Сверьтесь со своим компилятором, если в сомнении.
Можно использовать эти isnan()
функция, но необходимо включать математическую библиотеку C.
#include <cmath>
, Поскольку эта функция является частью C99, это не доступно везде. Если Ваш поставщик не предоставляет функцию, можно также определить собственный вариант для совместимости.
inline bool isnan(double x) {
return x != x;
}
Можно использовать numeric_limits<float>::quiet_NaN( )
определенный в limits
стандартная библиотека для тестирования с. Существует отдельная константа, определенная для double
.
#include <iostream>
#include <math.h>
#include <limits>
using namespace std;
int main( )
{
cout << "The quiet NaN for type float is: "
<< numeric_limits<float>::quiet_NaN( )
<< endl;
float f_nan = numeric_limits<float>::quiet_NaN();
if( isnan(f_nan) )
{
cout << "Float was Not a Number: " << f_nan << endl;
}
return 0;
}
я не знаю, работает ли это над всеми платформами, когда я только протестировал с g ++ на Linux.
Существует станд.:: isnan, если Вы компилятор поддерживаете c99 расширения, но я не уверен, делает ли mingw.
Вот небольшая функция, которая должна работать, если Ваш компилятор не имеет стандартной функции:
bool custom_isnan(double var)
{
volatile double d = var;
return d != d;
}
Существует также библиотека только для заголовка существующие в Повышении, которые имеют аккуратные инструменты для контакта с типами данных с плавающей точкой
#include <boost/math/special_functions/fpclassify.hpp>
, Вы получаете следующие функции:
template <class T> bool isfinite(T z);
template <class T> bool isinf(T t);
template <class T> bool isnan(T t);
template <class T> bool isnormal(T t);
, Если у Вас есть время затем, взглянули на целый Математический инструментарий от Повышения, он имеет много полезных инструментов и растет быстро.
Также при контакте с плаванием и неплавающими точками это могла бы быть хорошая идея посмотреть Числовые Преобразования .
На x86-64 у Вас могут быть чрезвычайно быстрые методы для проверки NaN и бесконечность, которые работают независимо от -ffast-math
параметр компилятора. (f != f
, std::isnan
, std::isinf
всегда урожай false
с -ffast-math
).
Тестирование на NaN, бесконечность и конечные числа может легко быть сделано путем проверки на максимальную экспоненту. бесконечность является максимальной экспонентой с нулевой мантиссой, NaN является максимальной экспонентой и ненулевой мантиссой. Экспонента хранится в следующих битах после самого верхнего знакового бита, так, чтобы мы могли просто сдвиг влево, чтобы избавиться от знакового бита и сделать экспоненту самыми верхними битами, никакое маскирование (operator&
) не необходимо:
static inline uint64_t load_ieee754_rep(double a) {
uint64_t r;
static_assert(sizeof r == sizeof a, "Unexpected sizes.");
std::memcpy(&r, &a, sizeof a); // Generates movq instruction.
return r;
}
static inline uint32_t load_ieee754_rep(float a) {
uint32_t r;
static_assert(sizeof r == sizeof a, "Unexpected sizes.");
std::memcpy(&r, &a, sizeof a); // Generates movd instruction.
return r;
}
constexpr uint64_t inf_double_shl1 = UINT64_C(0xffe0000000000000);
constexpr uint32_t inf_float_shl1 = UINT32_C(0xff000000);
// The shift left removes the sign bit. The exponent moves into the topmost bits,
// so that plain unsigned comparison is enough.
static inline bool isnan2(double a) { return load_ieee754_rep(a) << 1 > inf_double_shl1; }
static inline bool isinf2(double a) { return load_ieee754_rep(a) << 1 == inf_double_shl1; }
static inline bool isfinite2(double a) { return load_ieee754_rep(a) << 1 < inf_double_shl1; }
static inline bool isnan2(float a) { return load_ieee754_rep(a) << 1 > inf_float_shl1; }
static inline bool isinf2(float a) { return load_ieee754_rep(a) << 1 == inf_float_shl1; }
static inline bool isfinite2(float a) { return load_ieee754_rep(a) << 1 < inf_float_shl1; }
std
версии [1 110] и isfinite
загрузка 2 double/float
константы от [1 113] сегмент и в худшем варианте развития событий они могут вызвать 2 неудачных обращения в кэш данных. Вышеупомянутые версии не загружают данных, inf_double_shl1
и inf_float_shl1
, константы кодируются как непосредственные операнды в инструкции по сборке.
Быстрее isnan2
всего 2 инструкции по сборке:
bool isnan2(double a) {
bool r;
asm(".intel_syntax noprefix"
"\n\t ucomisd %1, %1"
"\n\t setp %b0"
"\n\t .att_syntax prefix"
: "=g" (r)
: "x" (a)
: "cc"
);
return r;
}
Использование то, что ucomisd
флаг четности систем команд, если каким-либо аргументом является NaN. Это - то, как std::isnan
работы, когда никакой -ffast-math
опции указан.
В текущей стандартной библиотеке C++ отсутствует функция isnan()
. Она была введена в C99 и определена как макро, а не как функция. Элементы стандартной библиотеки, определённые С99, не являются частью текущего стандарта ISO/IEC 14882:1998 и его обновления ISO/IEC 14882:2003.
В 2005 году был предложен Технический отчет 1. TR1 обеспечивает совместимость с C99 до C++. Несмотря на то, что он никогда не был официально принят, чтобы стать стандартом C++, многие (GCC 4.0+ или Visual C++ 9.0+ реализации C++ предоставляют возможности TR1, все или только некоторые из них (Visual C++ 9.0 не предоставляет математические функции C99).
Если TR1 доступен, то cmath
включает элементы C99, такие как isnan()
, isfinite()
и т.д., но они определены как функции, а не как макросы, обычно в std::tr1::
пространстве имён, хотя многие реализации (i. например, GCC 4+ на Linux или в XCode на Mac OS X 10.5+) вводят их непосредственно в std::
, так что std::isnan
хорошо определено.
Более того, некоторые реализации C++ все еще делают макрос C99 isnan()
доступным для C++ (включенный через cmath
или math.h
), что может вызвать больше путаницы, и разработчики могут предположить, что это стандартное поведение.
Заметка о Viusal C++, как упоминалось выше, не предоставляет std::isnan
и std::tr1::isnan
, но предоставляет функцию расширения, определяемую как _isnan()
, которая была доступна с Visual C++ 6.0
On XCode, это еще более забавно. Как уже упоминалось, GCC 4+ определяет std::isnan
. Для старых версий компилятора и библиотеки формы XCode, кажется (вот соответствующая дискуссия), не успел проверить себя) определены две функции, __inline_isnand()
на Intel и __isnand()
на Power PC.