ant*_*rez 9 c double printf integer casting
在Redis(http://code.google.com/p/redis)中有与元素相关联的分数,以便对这些元素进行排序.这个分数是双倍的,即使许多用户实际按整数排序(例如unix次).
保存数据库时,我们需要编写这个双打ok磁盘.这是目前使用的:
snprintf((char*)buf+1,sizeof(buf)-1,"%.17g",val);
Run Code Online (Sandbox Code Playgroud)
此外,还检查无穷大和非数字条件,以便在最终数据库文件中表示这一点.
不幸的是,将double转换为字符串表示非常慢.虽然我们在Redis中有一个函数,它以更快的方式将整数转换为字符串表示形式.所以我的想法是检查是否可以将double转换为整数而不丢失数据,然后使用该函数将整数转换为字符串(如果这是真的).
为了提供良好的加速,当然整数"等价"的测试必须快.所以我使用的技巧可能是未定义的行为,但在实践中效果很好.像这样的东西:
double x = ... some value ...
if (x == (double)((long long)x))
use_the_fast_integer_function((long long)x);
else
use_the_slow_snprintf(x);
Run Code Online (Sandbox Code Playgroud)
在我的推理中,上面的双重转换将double转换为long,然后转换为整数.如果范围适合,并且没有小数部分,则该数字将在转换后继续存在,并且与初始数字完全相同.
因为我想确保这不会破坏某些系统中的东西,我加入freenode上的#c并且我受到了很多侮辱;)所以我现在正在尝试这里.
有没有一种标准的方法来做我想要做的事情而不超出ANSI C?否则,上面的代码是否适用于当前Redis目标的所有Posix系统?那就是现在运行Linux/Mac OS X/*BSD/Solaris的拱门?
为了使代码更健全,我可以添加的是在尝试强制转换之前对double的范围进行显式检查.
感谢您的任何帮助.
也许一些旧时尚定点数学可以帮助你.如果您将double转换为固定点值,您仍然可以获得小数精度,并且转换为字符串就像添加单个shift函数的int一样简单.
另一个想法是滚动你自己的snprintf()函数.许多FPU单元本身支持从double到int的转换,因此应该是快速的.将其转换为字符串也很简单.
只是为您提供一些随意的想法.