在 Redis ( http://code.google.com/p/redis ) 中有与元素相关联的分数,以便对这些元素进行排序。这个分数是双倍的,即使许多用户实际上按整数排序(例如 unix 时间)。
保存数据库后我们需要写这个double ok磁盘。这是目前使用的:
snprintf((char*)buf+1,sizeof(buf)-1,"%.17g",val);
另外检查无穷大和非数字条件,以便在最终数据库文件中也表示这一点。
不幸的是,将 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);
在我的推理中,上面的双转换将 double 转换为长整型,然后再转换回整数。如果范围合适,并且没有小数部分,则该数字将在转换后继续存在,并且与初始数字完全相同。
因为我想确保这不会破坏某些系统,所以我在 freenode 上加入了#c,但我受到了很多侮辱;)所以我现在在这里尝试。
有没有一种标准方法可以在不超出 ANSI C 的情况下完成我想做的事情?否则,上面的代码是否应该适用于当前 Redis 所针对的所有 Posix 系统?也就是说,现在正在运行 Linux/Mac OS X/*BSD/Solaris 的拱门?
为了使代码更清晰,我可以添加的是在尝试转换之前显式检查 double 的范围。
感谢您的帮助。
最佳答案
也许一些老式的定点数学可以帮助您。如果您将 double 转换为定点值,您仍然可以获得小数精度,并且转换为字符串就像使用 int 一样简单,只需添加一个移位函数。
另一个想法是推出您自己的 snprintf() 函数。许多 FPU 单元本身支持从 double 到 int 的转换,因此应该快如闪电。将其转换为字符串也很简单。
只是给你一些随机的想法。
关于将 double 转换为整数以提高速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2821000/