【轉】Cocoa中的位與位元運算

來源:互聯網
上載者:User

標籤:

轉自:http://www.tuicool.com/articles/niEVjy介紹

位操作是程式設計中對位元模式或位元的一元和二元操作. 在許多古老的微處理器上, 位元運算比加減運算略快, 通常位元運算比乘除法運算要快很多. 在現代架構中, 情況並非如此:位元運算的運算速度通常與加法運算相同(仍然快於乘法運算).(摘自wikipedia)

OC作為c的擴充和超集,位元運算自然使用的是c的操作符。c提供了6個位操作符,$,|,^,~,<<,>>。本文不打算做位元運算的基礎教學,只介紹一些開發中能用到的情境。

提高運算速度

如前一段所說,位元運算的運算速度是通常與加法速度相當,但是快於乘法運算的。故而如果我們的程式對效能有要求,我們可以使用位元運算來提高運算速度。比如:

  • 乘以2:n << 1;
  • 除以2:n >> 1;
  • 乘以2的m次方:n << m;
  • 除以2的m次方:n >> m;
  • 判斷奇偶:(n & 1) == 1;
  • 求平均數:(a + b) >> 1;
  • ……

基於乘除法的位元運算提速還有很多,這裡不一一列舉。需要注意的是,你應當只在遇到效能瓶頸的時候,並且瓶頸的確是計算的時候才這麼做。因為使用位元運算並不利於程式的可讀性和可維護性。(科學計算除外)

壓縮空間

以前接觸過ACM的筒子們應該對狀態壓縮不陌生,狀態壓縮的目的在於把一個大資料用有限的記憶體空間來進行表示。比如 Programming Pearls 裡面的一個經典樣本:如何對最多有一千萬條不重複的7位整數(電話號碼)進行排序?且可使用的記憶體空間有大約1MB多。

顯而易見的常規做法既是做一個基於磁碟操作的外排序。然而如果轉換一下思路,充分的使用記憶體中的每一個位,加上不存在重複的電話號碼,以及不存在0和1開頭的電話號碼。我們只需要使用1000萬個位(大約1.2mb),就能以集合的方式在記憶體裡標記下所有的資料,從而輕鬆的實現位排序。此種方法大幅度的減少了IO時間,從而獲得巨大的效能提升。

ACM裡面有大量的如果使用位來壓縮空間的樣本,狀態壓縮的動態規劃等,此處不做展開,只告訴讀者,充分的使用記憶體的每一個位,經常能帶來意想不到的收穫。但需要注意的是,狀態的壓縮和提取,都需要一定的計算量,有時一味的追求狀態壓縮,反而會降低效率。

表示資料

比較經典的一個應用情境,使用一串24位的十六機制數字來表現一個RGB顏色(或者32位來表示ARGB)。由於PS,Web以及各類色彩選擇工具,都能快速的取出RGB的Hex值,但是UIColor沒有對應的方法。故而我們可以寫出下面這樣一個UIColor的Category,來快速的用一個RGBHex產生一個UIColor。(源碼在 UIColor + CYHelper.h )

+ (UIColor *)colorWithRGBHex:(UInt32)hex{    return [UIColor colorWithRGBHex:hex alpha:1.0f];}+ (UIColor *)colorWithRGBHex:(UInt32)hex alpha:(CGFloat)alpha{    int r = (hex >> 16) & 0xFF;    int g = (hex >> 8) & 0xFF;    int b = (hex) & 0xFF;    return [UIColor colorWithRed:r / 255.0f green:g / 255.0f blue:b / 255.0f alpha:alpha];}
狀態與選項
typedef NS_OPTIONS(NSUInteger, UIViewAnimationOptions) {    UIViewAnimationOptionLayoutSubviews            = 1 <<  0,    UIViewAnimationOptionAllowUserInteraction      = 1 <<  1, // turn on user interaction while animating    UIViewAnimationOptionBeginFromCurrentState     = 1 <<  2, // start all views from current value, not initial value    UIViewAnimationOptionRepeat                    = 1 <<  3, // repeat animation indefinitely    UIViewAnimationOptionAutoreverse               = 1 <<  4, // if repeat, run animation back and forth    UIViewAnimationOptionOverrideInheritedDuration = 1 <<  5, // ignore nested duration    UIViewAnimationOptionOverrideInheritedCurve    = 1 <<  6, // ignore nested curve    UIViewAnimationOptionAllowAnimatedContent      = 1 <<  7, // animate contents (applies to transitions only)    UIViewAnimationOptionShowHideTransitionViews   = 1 <<  8, // flip to/from hidden state instead of adding/removing    UIViewAnimationOptionOverrideInheritedOptions  = 1 <<  9, // do not inherit any options or animation type    UIViewAnimationOptionCurveEaseInOut            = 0 << 16, // default    UIViewAnimationOptionCurveEaseIn               = 1 << 16,    UIViewAnimationOptionCurveEaseOut              = 2 << 16,    UIViewAnimationOptionCurveLinear               = 3 << 16,    UIViewAnimationOptionTransitionNone            = 0 << 20, // default    UIViewAnimationOptionTransitionFlipFromLeft    = 1 << 20,    UIViewAnimationOptionTransitionFlipFromRight   = 2 << 20,    UIViewAnimationOptionTransitionCurlUp          = 3 << 20,    UIViewAnimationOptionTransitionCurlDown        = 4 << 20,    UIViewAnimationOptionTransitionCrossDissolve   = 5 << 20,    UIViewAnimationOptionTransitionFlipFromTop     = 6 << 20,    UIViewAnimationOptionTransitionFlipFromBottom  = 7 << 20,} NS_ENUM_AVAILABLE_IOS(4_0);

我們觀察Apple在UIViewAnimationOptions的枚舉變數,使用了一個NSUInteger就表示了UIViewAnimation所需的所有Option。其中0~9十個是互不影響的可同時存在option。16~19,20~24使用了4位來表示互斥的option。

如此定義了之後,對UIViewAnimationOptions的賦值變得尤為簡單,使用 | 操作符既可以獲得一個給對應的option位賦值後的結果。例如:

    [UIView animateWithDuration:1.0                          delay:0                        options:UIViewAnimationOptionAllowUserInteraction                             | UIViewAnimationOptionBeginFromCurrentState                             | UIViewAnimationOptionCurveEaseIn                     animations:{...}                     completion:{...}];

提取也比較簡單,使用 & 操作符 和 >> 操作符,就可以輕鬆判定某個位有沒有被設定,以及提取某些狀態位,例如:

UIViewAnimationOptions option = UIViewAnimationOptionAllowUserInteraction                                | UIViewAnimationOptionBeginFromCurrentState                                | UIViewAnimationOptionCurveEaseIn                                | UIViewAnimationOptionTransitionCrossDissolve;if (option & UIViewAnimationOptionAllowUserInteraction) {    NSLog(@"UIViewAnimationOptionAllowUserInteraction has been set");}if (option & UIViewAnimationOptionBeginFromCurrentState) {    NSLog(@"UIViewAnimationOptionBeginFromCurrentState has been set");}UInt8 optionCurve = option >> 16 & 0xf;if (optionCurve == 1) {    NSLog(@"UIViewAnimationOptionCurveEaseIn has been set");}UInt8 optionTransition = option >> 20 & 0xf;if (optionTransition == 5) {    NSLog(@"UIViewAnimationOptionTransitionCrossDissolve has been set");}

這裡最需要注意的地方就是,對互斥的狀態的設定必須尤為小心,如果你這麼寫:

UIViewAnimationOptions badOption = UIViewAnimationOptionCurveEaseIn | UIViewAnimationOptionCurveEaseOut;UInt8 oops = badOption >> 16 & 0xf;NSLog(@"Sorry, it‘s not UIViewAnimationOptionCurveEaseInOut");NSLog(@"oops = %d, you got UIViewAnimationOptionCurveLinear", oops);
聯絡我
  • 寫郵件:lancy1014#gmail.com
  • 關注我的 微博
  • Fo我的 Github
  • 在這裡寫評論留言

Lancy

9.27

【轉】Cocoa中的位與位元運算

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.