在支持基本的位操作(移動)這個工程的任何語言 - 即使語言不明確地使用0
和1
爲FALSE
和TRUE
。
C#樣品:
// Explanatory version:
static int Sign(int val)
{
val = -(int)((uint)val >> 31); // int is 32 bit, so shift by n - 1.
// uval now contains -1 for negative and 0 for positive.
return val * 2 + 1;
// -1 * 2 + 1 = -1
// 0 * 2 + 1 = +1
}
// Terse form:
static int Sign(int val)
{
return 1 - (int)((uint)val >> 31) * 2;
}
這是因爲如何負數上小端two's complement硬件(如86/64)被表示。基本上,數字中的第一位對於負值將爲'1'(請參閱本文中的示例)。
- 首先我們將它轉換爲無符號格式。這是爲了消除語言可能對簽名格式轉換操作(例如.Net)的任何特殊處理。
- 在這個階段,我們可能會做一個
AND
的操作,並且0x80000000
。這將消除與該值無關的位。我們不需要這樣做,因爲輪班的工作原理(如果您的語言只有ROL和ROR,您需要先執行此操作)。
- 我們將值右移31位。移位運算符將'銷燬'任何'結束'的位 - 因此我們在位
2^0
的左邊留下1或0。這意味着如果該值爲負值,則該值爲1,如果爲正值,則該值爲0.
- 我們將其轉換回int,然後使用簡單的數學將0和1分別映射爲1和-1 。
如果你是針對big-endian,我認爲只要改變班次應該會產生正確的結果。
爲什麼?您的循環增量示例實際上比第二個示例更慢,並且(更重要的是)可讀性更差。爲什麼你需要第一個較慢,較不可讀的版本?哦,'i = ++ i%max'在技術上與第二個不相同,除非你也假設沒有其他的操作來處理'i'。 – cletus 2010-07-05 00:51:09
「i = ++ i%max;」有未定義的行爲。因此,如果需要的話,編譯器可以使其比其他所有東西更快。 – 2010-07-05 01:01:54
順便說一下,「遺傳算法」與這個問題有什麼關係? – 2010-07-05 01:02:43