2017-06-14 24 views
-1

包装一个数字系统内的数,则索引具有重复组,其中第0索引始终为0例如,索引集表。将作为直通4C++中没有IF语句的数字系统之间包装浮点数?

INDEX: 0,1,2,3,4,5,6,7,8,9,10,11,12 
RESULT:0,1,2,3,4,0,1,2,3,4,0,1,2,3 

为范围0如下关联你可以看到这是类似于模量,直到你做负数,例如,范围-3至3,关系看起来像

INDEX | RESULT 
    -9|-2 
    -8|-1 
    -7|0 
    -6|1 
    -5|2 
    -4|3 
    -3|-3 
    -2|-2 
    -1|-1 
    0|0 
    1|1 
    2|2 
    3|3 
    4|-3 
    5|-2 
    6|-1 

等,等第四。

这也可以应用于一组小数。 我想编写一个函数,可以包装一个范围的浮点数,但要优化它,我不想使用IF语句或循环。我希望有一个数学解决方案,以便在不中断处理器训练的情况下处理这个过程非常简单,快速。

如何实现这样的系统?

对此的任何指导都会很棒!

+0

欢迎堆栈溢出。请花些时间阅读[The Tour](http://stackoverflow.com/tour),并参阅[帮助中心](http://stackoverflow.com/help/asking)中的资料,了解您可以在这里问。 –

+0

谢谢。我以前来过这里,但往往因为问题不好而删除我的账户。 – tuskiomi

+0

只需提问有效的问题即可。 –

回答

2

让我们假设,我们得到包裹开放范围(a0,a1)其中a0<0a1>0和输入号码是x我将开始与

x' = ((x/a0) - floor(x/a0))*a0 // negative x 
x' = ((x/a1) - floor(x/a1))*a1 // positive x 

现在唯一的问题进行试验如何决定使用哪一个没有分支(if语句) 。我会使用二进制位操作整数表示float值。符号位是MSBfloat是32位。因此,首先获得浮子的符号值,然后将其转换为01

unsigned int *px=(unsigned int*)&x; 
float a=(unsigned int)(px[0]>>31); 

当心unsigned int必须是相同的位宽度或更小(但然后使用粗的正确的比特移位)比float我通常使用DWORD这样的事情,但并不是所有的编译器都知道这样的类型(它也应该在windows.h btw中定义)。现在只需使用它来选择两个方程式。当我把所有的一起C++

float wrap(float x,float a0,float a1) 
    { 
    float a; 
    a=x/a0; a0*=(a-floor(a)); // x<=0 
    a=x/a1; a1*=(a-floor(a)); // x>=0 
    unsigned int *px=(unsigned int*)&x; // px is integer representaion of x 
    a=(unsigned int)(px[0]>>31); // a = 0 for x>=0 and a = 1 for x<=0 
    // now just combine 
    a0*=( a); 
    a1*=(1.0-a); 
    return a0+a1; 
    } 

这导致了一系列(-3,+3)

x | x' 
--------------- 
-6.25 | -0.25 
-6.00 | 0.00 
-5.75 | -2.75 
-5.50 | -2.50 
-5.25 | -2.25 
-5.00 | -2.00 
-4.75 | -1.75 
-4.50 | -1.50 
-4.25 | -1.25 
-4.00 | -1.00 
-3.75 | -0.75 
-3.50 | -0.50 
-3.25 | -0.25 
-3.00 | 0.00 
-2.75 | -2.75 
-2.50 | -2.50 
-2.25 | -2.25 
-2.00 | -2.00 
-1.75 | -1.75 
-1.50 | -1.50 
-1.25 | -1.25 
-1.00 | -1.00 
-0.75 | -0.75 
-0.50 | -0.50 
-0.25 | -0.25 
--------------- 
    0.00 | 0.00 
--------------- 
    0.25 | 0.25 
    0.50 | 0.50 
    0.75 | 0.75 
    1.00 | 1.00 
    1.25 | 1.25 
    1.50 | 1.50 
    1.75 | 1.75 
    2.00 | 2.00 
    2.25 | 2.25 
    2.50 | 2.50 
    2.75 | 2.75 
    3.00 | 0.00 
    3.25 | 0.25 
    3.50 | 0.50 
    3.75 | 0.75 
    4.00 | 1.00 
    4.25 | 1.25 
    4.50 | 1.50 
    4.75 | 1.75 
    5.00 | 2.00 
    5.25 | 2.25 
    5.50 | 2.50 
    5.75 | 2.75 
    6.00 | 0.00 
    6.25 | 0.25