作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我们的服务器应用程序在热代码路径中做了很多整数测试,目前我们使用以下函数:
inline int IsInteger(double n)
{
return n-floor(n) < 1e-8
}
这个函数在我们的工作量中非常热,所以我希望它尽可能快。如果可以的话,我也想消除“地板”库调用。有什么建议吗?
最佳答案
这里有几个答案:
#include <stdint.h>
#include <stdio.h>
#include <math.h>
int IsInteger1(double n)
{
union
{
uint64_t i;
double d;
} u;
u.d = n;
int exponent = ((u.i >> 52) & 0x7FF) - 1023;
uint64_t mantissa = (u.i & 0x000FFFFFFFFFFFFFllu);
return n == 0.0 ||
exponent >= 52 ||
(exponent >= 0 && (mantissa << (12 + exponent)) == 0);
}
int IsInteger2(double n)
{
return n - (double)(int)n == 0.0;
}
int IsInteger3(double n)
{
return n - floor(n) == 0.0;
}
还有一个测试工具:
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
int IsInteger1(double);
int IsInteger2(double);
int IsInteger3(double);
#define TIMEIT(expr, N) \
gettimeofday(&start, NULL); \
for(i = 0; i < N; i++) \
{ \
expr; \
} \
gettimeofday(&end, NULL); \
printf("%s: %f\n", #expr, (end.tv_sec - start.tv_sec) + 0.000001 * (end.tv_usec - start.tv_usec))
int main(int argc, char **argv)
{
const int N = 100000000;
struct timeval start, end;
int i;
double d = strtod(argv[1], NULL);
printf("d=%lf %d %d %d\n", d, IsInteger(d), IsInteger2(d), IsInteger3(d));
TIMEIT((void)0, N);
TIMEIT(IsInteger1(d), N);
TIMEIT(IsInteger2(d), N);
TIMEIT(IsInteger3(d), N);
return 0;
}
编译为:
gcc isinteger.c -O3 -c -o isinteger.o
gcc main.c isinteger.o -o isinteger
我在 Intel Core Duo 上的结果:
$ ./isinteger 12345
d=12345.000000 1 1 1
(void)0: 0.357215
IsInteger1(d): 2.017716
IsInteger2(d): 1.158590
IsInteger3(d): 2.746216
结论:位旋转并不像我猜想的那么快。额外的分支可能是杀死它的原因,即使它避免了浮点运算。如今,FPU 已经足够快了,执行 double
到 int
转换或 floor
真的没那么慢。
关于c - 测试双数是否为整数的最快方法是什么(在现代英特尔 X86 处理器中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1944119/
我正在尝试使用内联汇编进行试验,我正在尝试在内联汇编中添加十进制数(不,不是整数)。问题是,当我调用以下函数时: inline double ADD(double num1, double num2)
我有一个名为“a”的数据类型为 double 的数字,当这个数字小于 0.5 时,说b = 1 - a没有错误。但是当 a > 0.5 时,我说b = 1 - a代码中的该点存在错误(执行该特定行之前
我需要将双数添加到 ol 列表中。一个例子是: 欢迎访客1.1.介绍1.2.更多信息1.3.更多信息1.4.更多信息1.5.更多信息 另一个OL2.1.更多信息2.2.更多信息2.3.更多信息 我知道
我正在尝试将一些代码从 C++ 转换为 JavaScript,但我对 int、doubles、NaN 和解析 float 感到非常困惑。我想!? Z = T - 14 - (1); while (Z
我是一名优秀的程序员,十分优秀!