в Redis (http://code.google.com/p/redis) есть оценки, связанные с элементами, чтобы отсортировать эти элементы. Эти оценки удваиваются, даже если многие пользователи на самом деле сортируют по целым числам (например, раз Unix).
Когда база данных сохранена, нам нужно записать это на двоичных дисках. Это то, что используется в настоящее время:
snprintf((char*)buf+1,sizeof(buf)-1,"%.17g",val);
Дополнительно проверяются условия бесконечности и не числа, чтобы представить это в конечном файле базы данных.
К сожалению, преобразование double в строковое представление довольно медленное. В то время как у нас есть функция в Redis, которая намного быстрее преобразует целое число в строковое представление. Поэтому моя идея состояла в том, чтобы проверить, может ли двойное число быть преобразовано в целое число без потери данных, а затем с помощью функции превратить целое число в строку, если это правда.
Для этого, чтобы обеспечить хорошее ускорение, конечно, тест на целочисленную "эквивалентность" должен быть быстрым. Таким образом, я использовал трюк, который, вероятно, неопределенное поведение, но на практике он работал очень хорошо. Примерно так:
double x = ... some value ...
if (x == (double)((long long)x))
use_the_fast_integer_function((long long)x);
else
use_the_slow_snprintf(x);
По моим рассуждениям, приведенное выше двойное приведение преобразует двойное в длинное, а затем обратно в целое число. Если диапазон совпадает, а десятичная часть отсутствует, число сохраняется после преобразования и будет точно таким же, как и исходное число.
Поскольку я хотел убедиться, что в какой-то системе это не сломается, я присоединился к #c на freenode и получил много оскорблений;) Поэтому я сейчас пытаюсь здесь.
Есть ли стандартный способ сделать то, что я пытаюсь сделать, не выходя за пределы ANSI C? Иначе, должен ли вышеуказанный код работать во всех системах Posix, которые в настоящее время предназначены для Redis? То есть, арки, где сейчас работают Linux / Mac OS X / * BSD / Solaris?
То, что я могу добавить для того, чтобы сделать код более разумным, - это явная проверка диапазона double перед попыткой приведения вообще.
Спасибо за любую помощь.