在Redis(http://code.google.com/p/redis)中将双精度转换为整数以便将元素与元素相关联,以便将此元素进行排序。即使许多用户实际按整数排序(例如unix时间),该分数也是双打的。为了获得速度
当数据库被保存时,我们需要写这个双打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 casting将double转换成long,然后返回到整数。如果范围适合,并且没有小数部分,则该数字将在转换后存活,并且与初始数字完全相同。因为我想确保这不会破坏某些系统中的某些东西,所以我加入了freenode上的#c,并受到很多侮辱;)因此,我现在正在尝试这里。
有没有一种标准的方法来做我想要做的事情,而不需要去ANSI C之外?否则,上述代码是否应该适用于当前Redis所针对的所有Posix系统?也就是说,Linux/Mac OS X/* BSD/Solaris现在正在运行的拱?
为了使代码更加完整,我可以添加的内容是在尝试执行演员之前明确检查双精度的范围。
谢谢你的帮助。
侮辱侮辱,男人。我不知道答案,但我希望你找到答案。 – mmr 2010-05-12 17:06:03
如果有帮助,http://stackoverflow.com/questions/638376/what-is-the-most-reliable-way-of-checking-if-a-floating-point-variable-is-an-inte was a在C#中检查这种方式。我还没有找到一个C版本。 – 2010-05-12 17:15:13
或者,我可以使用modff()来检查小数部分是否为零?然后检查整体部分的范围是否在很长的范围内,如果属实,则施放它。 – antirez 2010-05-12 17:43:39