HLH
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    # 2018q3 Homework5 (bits) contributed by < `jesus255221` > ## BitCount BitCount 這個函數是裡面比較有挑戰性的題目,[漢明重量](https://zh.wikipedia.org/wiki/%E6%B1%89%E6%98%8E%E9%87%8D%E9%87%8F)便可以快速的計算出 bit 唯一的個數 ```clike= int bitCount(int x) { int y = 0, count = 0; const int a = 0x55, b = 0x33, c = 0x0F, mask = 0xFF; y = x & mask; y = (y & a) + ((y >> 1) & a); y = (y & b) + ((y >> 2) & b); y = (y & c) + ((y >> 4) & c); count += y; y = x >> 8 & mask; y = (y & a) + ((y >> 1) & a); y = (y & b) + ((y >> 2) & b); y = (y & c) + ((y >> 4) & c); count += y; y = x >> 16 & mask; y = (y & a) + ((y >> 1) & a); y = (y & b) + ((y >> 2) & b); y = (y & c) + ((y >> 4) & c); count += y; y = x >> 24 & mask; y = (y & a) + ((y >> 1) & a); y = (y & b) + ((y >> 2) & b); y = (y & c) + ((y >> 4) & c); count += y; return count; } ``` 題目規定只能用`0xFF`以內的常數,所以必須要分四次做。 ## BitMatch 基本上 bitmatch 要做的是 NOT XOR,因為 NAND GATE 可以表示任何邏輯電路,又根據[維基百科](https://en.wikipedia.org/wiki/NAND_logic), `A'B + AB' = A XOR B` `((A + B')(A' + B))' = A XOR B` `((A'B)'(AB')')' = A XOR B` 這樣就順利換成 and gate 與 not gate (電機系沒白讀 ## BitReverse BitReverse 也可以利用 hamming weight 的概念,兩兩交換,四四交換。 ```clike= int bitReverse(int x) { int m1 = 0xaa << 24 | 0xaa << 16 | 0xaa << 8 | 0xaa, m2 = m1 >> 1; // 0xaaaaaaaa int m3 = 0xcc << 24 | 0xcc << 16 | 0xcc << 8 | 0xcc, m4 = m3 >> 2; // 0xcccccccc int m5 = 0xf0 << 24 | 0xf0 << 16 | 0xf0 << 8 | 0xf0, m6 = m5 >> 4; // 0xf0f0f0f0 int m7 = 0x00 << 24 | 0xff << 16 | 0x00 << 8 | 0xff, m8 = m7 >> 8; // 0x00ff00ff x = ((x & m1) >> 1 | (x & m2) << 1); x = ((x & m3) >> 2 | (x & m4) << 2); x = ((x & m5) >> 4 | (x & m6) << 4); x = ((x & m7) >> 8 | (x & m8) << 8); return ((x >> 16) | (x << 16)); } ``` ## Condition 傳遞為 1 的 bit, ```clike= int conditional(int x, int y, int z) { x = x | x << 1; x = x | x << 2; x = x | x << 4; x = x | x << 8; x = x | x << 16; x = x >> 31; //Sign extension if any bits are one return (x & y) | (~x & y); } ``` ## CountingLeadingZero 先用 1 把左手邊 RSB 全部補齊,全反向,再用 bitCount 來計算 leading zero。 ```clike= int countLeadingZero(int x) { x = x | x >> 1; x = x | x >> 2; x = x | x >> 4; x = x | x >> 8; x = x | x >> 16; x = ~x; return bitCount(x); } ``` ## dividePower2 Round to zero 代表向零捨去小數點。要修正的就是負數的除法,如果負數在第 n 位下面還有 1 ,則加一。 ```clike= int dividePower2(int x, int n) { int mask = ~1 + 1; mask = ~(mask << n); return (x >> n) + !!(x & mask & x >> 31); } ``` ## ezThreefourths 很簡單但是一開始沒想到,基本上就是把原數加三次,丟給`dividePower2` ```clike= int ezThreeFourths(int x) { int y = x + x + x; return dividePower2(y, 2); } ``` ## fitsBit 仔細觀察可表示範圍,在二補數範圍裡面,複數永遠可以表示的比正數更多一個,也就是說最小複數加一就是相對最大正數可以被表示的位元數。例如: `-8` 與 `|-8 + 1|`最小位元數應當相同。因為必須要判斷需要的位元數,必須把數值換成正的才能決定最小可以被表示的位元數。所以如果 x 為負數便讓它加一,然後換成正數再決定除 2^n 商是否為 0 ,如果是零則代表 n 可以表示比 x 更大的數,便回傳真。 ```clike= int fitsBits(int x, int n) { int sign_x = x >> 31; x = x + (~sign_x + 1); x = absVal(x); n = n + ~0;// n-- return !(x >> n); } ``` ## CountLeadingZero 把 MSB 的右邊全部補滿零,反向再計算 bit 數。 ```clike= int countLeadingZero(int x) { x = x | x >> 1; // Fill ones to the LSB x = x | x >> 2; x = x | x >> 4; x = x | x >> 8; x = x | x >> 16; x = ~x; return bitCount(x); // Calculate the left zeros } ``` ## Bitwise Greater than [來源](https://stackoverflow.com/questions/10096599/bitwise-operations-equivalent-of-greater-than-operator) 這段 code 實在太神奇了,我想了很久終於懂了 XOR 是在找 x 與 y 不同的 bits. 上面的一到六行傳遞了 MSB (也就是最大的不同的 bit )並且把 MSB 右邊都設成 1。 第七行就是要隔離 MSB 使其成為此數字中唯一的 1。 最有趣的是第八行,先討論符號,如果不同的 bit 在 sign bit,又這個 sign bit 是 y 的而不是 x 的,就會回傳 1,反之則回傳 0。如果這個不同的 bit 是數字位,又這個一是屬於 x 的,則回傳 1 ( x 與 y 必定有一個人是 1 有個人是 0),反之則回傳零。在MSB 上面只要 x > y 則 x 就必定大於 y 不管在正負數上皆如此( two's complement 中 -1 是 unsigned 數值中最大的),就是這樣精巧的設計。 ```clike= int isGreater(int x, int y) // Comes from stackoverflow { int diff = x ^ y; diff |= diff >> 1; diff |= diff >> 2; diff |= diff >> 4; diff |= diff >> 8; diff |= diff >> 16; diff &= ~(diff >> 1) | 0x80000000; diff &= (x ^ 0x80000000) & (y ^ 0x7fffffff); return !!diff; } ``` ## Bitwise log [來源](https://stackoverflow.com/questions/21442088/computing-the-floor-of-log-2x-using-only-bitwise-operators-in-c) ## leastBitPos 只要是 LSB ,右邊一定都是零或者沒有。在去負數的時候右邊都是一,再加一就會造成進位剛好在 LSB 的地方也會是一。 ```clike= int leastBitPos(int x) { return x & (~x + 1); } ``` ## FloatIsEqual 只要是 NaN 則 return 0,只要是 0 則 return 1 ```clike= int floatIsEqual(unsigned uf, unsigned ug) { int expo_f = (uf >> 23 & 0xFF); int mtsa_f = (uf & 0x7FFFFF); int expo_g = (ug >> 23 & 0xFF); int mtsa_g = (ug & 0x7FFFFF); if (expo_f == 0xFF && expo_g == 0xFF && !!mtsa_f && !!mtsa_g) { return 0; } else if (!expo_f && !expo_g && !mtsa_f && !mtsa_g) { return 1; } else { return !(uf ^ ug); } } ``` ## isPower2 [來源](http://forum.codecall.net/topic/50648-bitwise-manipulations-in-c/)給出了一個驚人的作法 ```clike= return !(x & (x-1)); ``` 不過負的會 overflow 所以改成以下因為 x 不應該是負的也不應該為零。 ```clike= int isPower2(int x) { int sign_x = x >> 31; return (!(x & (x-1))) & (~sign_x & !!x); } ``` ## floatInt2Float 因為 IEEE 754 的捨入規則,在處理 2 的 23 次方以上的數字要特別小心,必須注意捨入是否有超過最低位的一半 ```clike= unsigned floatInt2Float(int x) { int sign_x = x & 0x80000000u; if (x == 0) { return x; } else if (x == sign_x) { // x is the least number in the integer return 0xCF000000; } else { if (x < 0) { x = -x; } int expo = -1; int y = x; while (!!y) { y >>= 1; expo++; } // printf("%d\n",expo); if (expo > 23) { // if x >= 2 ^ 25 or x <= -2 ^ 25, it can no longer be // represented by float thoroughly. int mask = ~0; mask <<= expo - 23; int remainder = (~mask & x); //Get the remainder x >>= expo - 23; // Shift the number if (remainder > (1 << (expo - 24))) { x++; } else if (remainder == (1 << (expo - 24))) { x += (x & 1); } if (x >= (1 << 24)) { while (x >= (1 << 24)) { x >>= 1; expo++; } } } else { x <<= (23 - expo); // printf("%x\n",x); } x &= ~(0x800000); // Zero out the 24th bit return sign_x | x | (expo + 127) << 23; } } ``` ## rotateLeft 先把 1 送到最左邊,在利用 sign extension 來製造 mask,最後在 shift number 與利用 mask 來遮蔽不需要的 bit。 ```clike= int rotateLeft(int x, int n) { int mask = (1 << 31); // Produce mask mask >>= 32 + ~n + 1; mask <<= 1; return ((x << n & mask) | (x >> (32 + ~n + 1) & ~mask)); } ``` ## isAscii 只要傳近來的數字減掉 0x2f 與 0x3a 減掉此數字不同實為負數時,就不是 ascii ```clike= int isAsciiDigit(int x) { int sign_x = x >> 31; int y = 0x2f - x; int z = x - 0x3a; y >>= 31; z >>= 31; return 1 & y & z & ~sign_x; } ``` ## satAdd 只要正負號不對,mask 將會將其遮蔽 ```clike= int satAdd(int x, int y) { int sign_x = x >> 31, sign_y = y >> 31; int z = x + y; int sign_z = z >> 31; int msk = (sign_x & sign_y & ~sign_z) | (~sign_x & ~sign_y & sign_z); //++-, --+ are not allowed return (sign_x & sign_y & ~sign_z & (1 << 31)) | (~sign_x & ~sign_y & sign_z & ~(1 << 31)) | (~msk & z); } ``` ## TrueFiveEights 秉持著 input 一定會 Overflow 的態度,一開始先將 input x 除以八,記下餘數,之後在把餘數乘以五倍,再除以八。接下來就把剛剛的商與餘數的商加在一起,必要時再是捨五入即可。 ```clike= int trueFiveEighths(int x) { int remainder = 0, sign_x = x >> 31, mask = 0x7, true_remainder = 0; remainder = x & mask; // The mask for taking remainder remainder = (remainder << 2) + remainder; // The true remainder true_remainder = remainder & mask; remainder >>= 3; int answer = x >> 3; answer = answer + answer + answer + answer + answer; return answer + remainder + (sign_x & !!true_remainder); } ``` ## upperBits 麻煩的是有 32 與 0,不過這邊用的是不管 n 是多少,都減一,如果為負數則遮蔽所有位元 ```clike= int upperBits(int n) { int x = (1 << 31); n += ~0;//n-- int sign_n = n >> 31; x >>= (~sign_n & n); return x & ~sign_n; } ```

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully