2012-11-02 63 views
-4

如何製作輸出NOT(x)的程序?C++不輸出... +1負數

實施例:

  • 12至3
  • 0-1
  • 2至1

解釋:

  • 1100至0011
  • 0到1
  • 01至10

    printf("%i\n%i\n%i\n", ~12, ~0, ~2);

打印:

-13 
-1 
-3 

printf("%i\n%i\n%i\n", !12, !0, !2); 

打印:

0 
1 
0 
+2

嘗試使用'unsigned int'而不是'int'。 – andre

+10

告訴我,爲什麼NOT(0)在你的例子中是'1',但NOT(1)是'10'?我們應該怎麼知道'1'實際上是'01',而不是'000001'? – raina77ow

+0

NOT(1)= 0 ... 10是二進制的,十進制= 1. 1不是01也不是00001,它只是1,而不是(1)= 0. – user1794604

回答

5

你的可變參數對printf被晉升爲int,想想它作爲第一個變量的存儲位(INT),然後他們執行而不是位:現在

int x = 12;  // 0x0000000C 
int y = ~x;  // 0xFFFFFFF4 

y是帶負號的int值。

更改格式字符串和你的價值觀爲無符號,它可能是更接近你正在尋找:

int main(int argc, char *argv[]) 
{ 
    unsigned int x = 12; 
    unsigned int y = ~x; 
    printf("%u:%u\n",x,y); 
    return EXIT_SUCCESS; 
} 

結果:

12:4294967283 

如果您正在尋找功能由於printf()沒有本地位二進制打印功能,所以打印實際的「位」值是一個很好的起點,可以是found here。最後,如果所有你感興趣的翻轉是最重要的非零位,當輸入值爲零(0)時,一定要特別注意你的情況。你真的需要一個「這麼多對我來說很重要」的價值才能真正做到這一點。

編輯:一個非常低效BITSTRING:顯然,這將不無爲引模板參數一個數字型工作。自行決定使用(和危險)。

template<typename T, size_t N=sizeof(T)*8> 
std::string bit_string(T value, size_t maxbits=N) 
{ 
    static const char *one = "1"; 
    static const char *zero = "0"; 
    std::string result; 

    maxbits = std::min(maxbits, N); 
    for (size_t i=0;i<maxbits;i++) 
    { 
     result = ((value & T(1)) ? one : zero) + result; 
     value >>= 1; 
    } 
    return result; 
} 
0

好吧,如果你想要翻轉所有位在一個int,你可以從int max減去值,或翻轉總之,從short max減去......至少我認爲這就是你」再問。

3

你的第一個例子的工作方式是因爲負數的two's complement二進制表示法。

例如,值12實際上將以16位整數表示爲0000000000001100,並且很可能實際上將是32位整數。按位不是這個值是1111111111110011,這是-13的二進制補碼。

你的第二個示例代碼使用布爾型非運算符。 C++將任何非零值視爲true,並且「not true」的值始終爲false或整數0。類似地,!0表示「不是錯誤」,並且將返回-1作爲C++的「標準真實」值。 (因爲!0 == -1用於二進制補碼,所以使用該值,因此!false~false是等效操作。)

所以:你打算做的比你想象的要複雜。你所說的「NOT(x)」實際上是「二進制數的按位非」,被截斷爲有效數字的最小數目,並被解釋爲無符號數。這並不像聽起來那麼簡單!

有效數字部分尤爲重要。如果所有數字都是8位無符號數,那麼「NOT(2)」實際上是253而不是(如你所說你需要)1

這也是有趣的是,你的定義,意味着不是不再是可逆的:NOT(NOT(12))不是12,而且事實上NOT(12) = 3,然後NOT(3) =0

因此,爲了實現你想要什麼:(?這是2的最高功率小於你原來的號碼)

  1. 工作了你原來的號碼的最顯著的數字是什麼。 (代表這個值作爲sd供以後使用。)
  2. 按位,反轉你原來的號碼
  3. 位與與2^(sd) - 1

例如結果,與數字12

  1. 最有效數字是4(2^4 = 16)
  2. 反向數字(假設16位)是1111111111110011
  3. 2^4 - 1 = 15其中二進制是0000000000001111
  4. 1111111111110011 AND 0000000000001111 == 0000000000000011這是你想要的結果。
+1

所以基本上你在說什麼,我必須編寫我自己的函數,它取1和0,在第一個1(000100 - > 100)之前刪除所有0並將它們反轉? – user1794604

+0

如果您記得所有不需要的0將在轉換中轉換爲1,則可以更容易一些。基本上,你需要在倒置結果中遇到第一個'0'(當從左到右計數時)後面的所有內容。 – raina77ow

+0

是的,基本上 - 或者找到找到相同結果的另一種方式(比如@ raina77ow建議的)。你所描述的不是一個簡單的操作,所以解決方案並不像一次操作那麼簡單。 –