Указатель NULL
- это тот, который указывает на никуда. Когда вы разыскиваете указатель p
, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p
является нулевым указателем, местоположение, хранящееся в p
, является nowhere
, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception
.
В общем, это потому, что что-то не было правильно инициализировано.
Это зависит от того, если Вы хотите преобразование усечения или округляющееся и в какой точность. По умолчанию C выполнит преобразование усечения, когда Вы пойдете от плавания до интервала существуют инструкции по FPU, которые делают это, но это не ANSI C преобразование и существуют значительные протесты к использованию его (такие как знание состояния округления FPU). Так как ответ на Вашу проблему довольно сложен и зависит от некоторых переменных, которые Вы не выразили, я рекомендую эту статью о проблеме:
Упакованное преобразование с помощью SSE является безусловно самым быстрым методом, так как можно преобразовать несколько значений в той же инструкции. ffmpeg имеет большой блок для этого (главным образом для преобразования декодируемого вывода аудио к целочисленным образцам); проверьте его на некоторые примеры.
Наиболее часто используемый прием для плоскости x86/x87 код должен вынудить часть мантиссы плавания представить международную версию на 32 бита, следует.
64-разрядная версия аналогична. Версия Lua, отправленная выше, быстрее, но полагается на усечение дважды к 32-разрядному результату, поэтому это требует, чтобы x87 единица была установлена на двойную точность и не может быть адаптировано к дважды к 64-разрядному международному преобразованию.
хорошая вещь об этом коде - он, является абсолютно портативным для всех платформ, соответствующих IEEE 754, единственное сделанное предположение является режимом округления плавающей точки, установлен на самый близкий.Примечание: Портативный в смысле это компилирует и работает. Платформы кроме x86 обычно не извлекают выгоду очень из этой техники, если вообще.
static const float Snapper=3<<22;
union UFloatInt {
int i;
float f;
};
/** by Vlad Kaipetsky
portable assuming FP24 set to nearest rounding mode
efficient on x86 platform
*/
inline int toInt( float fval )
{
Assert( fabs(fval)<=0x003fffff ); // only 23 bit values handled
UFloatInt &fi = *(UFloatInt *)&fval;
fi.f += Snapper;
return ( (fi.i)&0x007fffff ) - 0x00400000;
}
Если можно гарантировать, что ЦП, выполняющий код, SSE3 совместимый (даже Pentium 5, JBB), можно позволить компилятору использовать свою инструкцию FISTTP (т.е.-msse3 для gcc). Это, кажется, делает, вещь как он должна была всегда делаться:
Примечание, что FISTTP отличается от FISTP (который имеет его проблемы, вызывая замедление). Это стало частью SSE3, но является на самом деле (единственное) улучшением X87-стороны.
Другой тогда ЦП X86, вероятно, сделал бы преобразование очень хорошо, так или иначе.:)
Кодовая база Lua имеет следующий отрывок, чтобы сделать это (регистрация src/luaconf.h с www.lua.org). Если бы Вы находите (ПОЭТОМУ находит), более быстрый путь, я уверен, что они были бы взволнованы.
, О, lua_Number
средства дважды.:)
/*
@@ lua_number2int is a macro to convert lua_Number to int.
@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
** CHANGE them if you know a faster way to convert a lua_Number to
** int (with any rounding method and without throwing errors) in your
** system. In Pentium machines, a naive typecast from double to int
** in C is extremely slow, so any alternative is worth trying.
*/
/* On a Pentium, resort to a trick */
#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \
(defined(__i386) || defined (_M_IX86) || defined(__i386__))
/* On a Microsoft compiler, use assembler */
#if defined(_MSC_VER)
#define lua_number2int(i,d) __asm fld d __asm fistp i
#define lua_number2integer(i,n) lua_number2int(i, n)
/* the next trick should work on any Pentium, but sometimes clashes
with a DirectX idiosyncrasy */
#else
union luai_Cast { double l_d; long l_l; };
#define lua_number2int(i,d) \
{ volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
#define lua_number2integer(i,n) lua_number2int(i, n)
#endif
/* this option always works, but may be slow */
#else
#define lua_number2int(i,d) ((i)=(int)(d))
#define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
#endif
Существует одна инструкция преобразовать плавающую точку в интервал в блоке: используйте инструкцию FISTP. Это выталкивает значение от стека с плавающей точкой, преобразовывает его в целое число, и затем хранит в в определенном адресе. Я не думаю, что был бы более быстрый путь (если Вы не используете расширенные системы команд как MMX или SSE, который я не знаком с).
Другая инструкция, КУЛАК, оставляет значение на стеке FP, но я не уверен, что это работает с измеренными местами назначения квадратического слова.
Если Вы действительно заботитесь о скорости этого, удостоверяются, что Ваш компилятор генерирует инструкцию по КУЛАКУ. В MSVC можно сделать, это с/QIfist, видит этот обзор
MSDN, можно также рассмотреть использование SSE intrinsics, чтобы сделать работу для Вас, видеть эту статью от Intel: http://softwarecommunity.intel.com/articles/eng/2076.htm
Обычно можно доверять компилятору, чтобы быть эффективными и корректными. Обычно нет ничего, чтобы быть полученным путем прокрутки собственных функций для чего-то, что уже существует в компиляторе.