2017-06-14 35 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