在C#中,以下代码返回2:
double d = 2.9;
int i = (int)d;
Debug.WriteLine(i);
Run Code Online (Sandbox Code Playgroud)
但是,在Javascript中,将我所知道的"double"转换为"int"的唯一方法是使用Math.round/floor/toFixed等.有没有一种方法可以在Javascript中转换为int而不进行舍入?我知道Number()的性能影响,所以我宁愿避免将其转换为字符串,如果可能的话.
我们在项目中进行了大量的浮点到整数转换.基本上,这样的事情
for(int i = 0; i < HUGE_NUMBER; i++)
int_array[i] = float_array[i];
Run Code Online (Sandbox Code Playgroud)
执行转换的默认C函数非常耗时.
是否有任何工作(可能是手动调整功能)可以加快一点点的过程?我们不太关心精度.
SSE2具有在单精度浮点数和32位整数之间转换向量的指令.
_mm_cvtps_epi32()_mm_cvtepi32_ps()但是没有双精度和64位整数的等价物.换句话说,他们失踪了:
_mm_cvtpd_epi64()_mm_cvtepi64_pd()似乎AVX也没有它们.
模拟这些内在函数的最有效方法是什么?
我有double x,和double y.我需要将其转换成int boxnum,其被定义为(地板)的索引,其中(x,y)在属于WIDTH x HEIGHT同大小的正方形网格BOX_SIZE.超过的坐标WIDTH被包裹回来; 同上HEIGHT.
我目前正在使用:
( (((int)(x))/BOX_SIZE)%WIDTH+ WIDTH*((((int)(y))/BOX_SIZE)%HEIGHT) )
Run Code Online (Sandbox Code Playgroud)
这句话目前占用了我执行时间的20%,如果我对负坐标完全安全,那就更糟糕了(大约40-50%):
( (( ((int)(x)) /BOX_SIZE)%WIDTH+WIDTH)%WIDTH
+WIDTH*(( (((int)(y)) /BOX_SIZE)%HEIGHT+HEIGHT)%HEIGHT) )
Run Code Online (Sandbox Code Playgroud)
我实际上正在考虑将应用程序完全转换为定点,只是为了避免这种情况,这样我就可以对我想要的部分进行掩码,而不是进行这种可怕的转换.
有没有更好的方法来进行这种双重> int转换?难道是值得的,以确保0<x<WIDTH*BOX_SIZE和0<y<HEIGHT*BOX_SIZE这样我就可以放下两个余数操作?(这样做很难在基准测试中不值得,除非它可能是一个重大改进)
编辑:在评论中进行适当的惩罚后,更多细节:
x并且y是一组(多达10 ^ 6)个粒子的坐标.我正在使用一种算法,它要求我在每个时间步,对一个框内的所有粒子做一些简单的求和.因此,我遍历粒子,计算粒子所在的盒子,然后将其用作添加到该盒子的数组索引.粒子通常移动得足够远,以至于它们过去的位置并不能表明它们未来的位置.这也是无序的,这意味着我不能对此做出任何假设.
WIDTH,HEIGHT以及BOX_SIZE在技术上是免费的,只要WIDTH和HEIGHT是的偶数倍BOX_SIZE.在实践中,它们都是指定的编译时间,并且是整数BOX_SIZE=1.我从运行一切WIDTH=HEIGHT=4到WIDTH=HEIGHT=512,虽然我平时对2(因为为什么不呢?),方功率WIDTH=37;HEIGHT=193应该没有问题的工作.
每个粒子每个时间步执行一次该计算是不可避免的; 在当前实现中,它执行两次.我尝试缓存该值以避免重新计算,但最终基准测试表现更差,所以我回去计算它两次.
基本测试运行10 particles/box * 100 WIDTH * …
我试图将Lua(5.1.5)中的字符串转换为整数,并检查该数字是否为有效整数(0~99999).但是,我发现lua_tonumber()在处理大整数时与lua_tointeger()有不同的行为.
int main()
{
int in;
double db;
lua_State* Lua = luaL_newstate();
luaL_openlibs(Lua);
lua_pushstring(Lua, "213232127162767162736718238168263816873");
db = lua_tonumber(Lua, -1);
in = lua_tointeger(Lua, -1);
printf("DOUBLE:%f\n", db); // DOUBLE:213232127162767176000119210017101447168.000000
printf("INT:%d\n", in); // INT:0
};
Run Code Online (Sandbox Code Playgroud)
如果我使用lua_tointeger(),它将返回0并将通过我的检查.
我检查了两个API描述,但我仍然不知道为什么他们有不同的行为.这些行为是否与机器无关?使用lua_tonumber()更好的方法吗?
我可以使用以下代码检查结果吗?(跨平台)
if (!lua_isnumber(Lua, -1)) { //error }
result = lua_tonumber(Lua, -1);
if (result < 0 || result > 99999) { // error2 }
// pass
Run Code Online (Sandbox Code Playgroud) 我真的需要在C中使用非常快的round()函数 - 它对于蒙特卡罗粒子建模是必要的:在每一步都需要将坐标包装到周期框中以计算体积交互:例如
for(int i=0; i < 3; i++)
{
coor.x[i] = a.XReal.x[i]-b.XReal.x[i];
coor.x[i] = coor.x[i] - SIZE[i]*round(coor.x[i]/SIZE[i]); //PBC
}
Run Code Online (Sandbox Code Playgroud)
我遇到过一些asm hacking with it,但我根本不理解asm :)这样的事情
inline int float2int2(float flt)
{
int intgr;
__asm__ __volatile__ ("fld %1; fistp %0;" : "=m" (intgr) : "m" (flt));
return intgr;
}
Run Code Online (Sandbox Code Playgroud)
对于固定边界,没有round(),它的工作速度更快.那么,也许有人知道更好的方式?...
每种编程语言都有自己的方法将整数转换为浮点数,将 01010 转换为其他 01010。如果您看到 ASM 生成的代码,它使用协处理器指令向用户隐藏真实值。
但实际情况如何呢?如何通过算法计算尾数、指数?
c ×4
performance ×3
c++ ×2
assembly ×1
avx ×1
casting ×1
int ×1
integer ×1
javascript ×1
lua ×1
modeling ×1
optimization ×1
simd ×1
sse ×1