C#解惑01: 奇數性

來源:互聯網
上載者:User
謎題01: 奇數性
    下面方法的目的是確定其唯一的參數是否為奇數。這個方法可行嗎?
    public static bool IsOdd(int i)
    {
      return i % 2 == 1;
    }
   
解惑01: 奇數性
    奇數可定義為被2整除餘數為1的整數。運算式i%2計算的是i除以2時所產生的餘數,因此看起來這個程式應該可行。遺憾的是,它不行;在四分之一的時間裡它返回的都是錯誤的答案。
    為什麼是四分之一?因為在所有的int數值中,有一半是負數,而IsOdd方法對所有負奇數的判斷都會失敗。在任何負整數上調用該方法都會返回false,無論該整數是偶數還是奇數。
    這是C#對取餘操作符(%)的定義所產生的後果。該操作符被定義為對所有的int數值a和所有的非零int數值b,都滿足下面的恒等式:
    (a / b) * b + (a % b) == a
    換句話說,如果用b整除a,將商乘以b,然後加上餘數,那麼就得到了最初的值a[C#語言規範 7.7.3]。該恒等式具有正確的含義,但是當與C#的截尾整數整除操作符[C#語言規範 7.7.2]相結合時,它就意味著: 當取餘操作返回一個非零的結果時,它與左運算元具有相同的正負符號。
    IsOdd方法以及它所基於的對術語“奇數”的定義都假設所有的餘數都是正數。雖然該假設對某些種類的整除是有意義的,但是C#的取餘操作是與捨棄整除結果小數部分的整數整除操作完全符合的。
    當i是一個負奇數時,i % 2等於-1而不是1,因此IsOdd方法錯誤地返回false。為了防止這種意外, 請測試你的方法在為每一個數值型參數傳遞負數、零和正數數值時,其行為是否正確。
    這個問題很容易改正。只需將i % 2與0而不是與1比較,並且使用相反的比較含義即可:
    public static bool IsOdd(int i)
    {
      return i % 2 != 0;
    }
    如果正在一個強調效能的環境中使用IsOdd方法,那麼用位操作符AND(&)替代取餘操作符會顯得更好:
    public static bool IsOdd(int i)
    {
      return (i & 1) != 0;
    }
    第二個版本運行起來可能比第一個版本要快得多,這取決於你使用的是什麼樣的平台和虛擬機器,並且不太可能出現運行得更慢的情況。按常規來說,整除和取餘操作與其他的算術和邏輯操作相比要慢一些。 倉促地最佳化是不好的,但是在上述情況下,更快的版本與最初的版本一樣清晰明白,所以沒有任何理由偏愛最初的版本。
    總之,無論何時使用了取餘操作符,都要考慮運算元和結果的符號。該操作符的行為在其運算元非負時是一目瞭然的,但是當一個或兩個運算元是負數時,它的行為就不那麼顯而易見了。

    C#解惑總目錄

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.