<rss
      xmlns:atom="http://www.w3.org/2005/Atom"
      xmlns:media="http://search.yahoo.com/mrss/"
      xmlns:content="http://purl.org/rss/1.0/modules/content/"
      xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
      xmlns:dc="http://purl.org/dc/elements/1.1/"
      version="2.0"
    >
      <channel>
        <title><![CDATA[Block of Vaz]]></title>
        <description><![CDATA[Random thought of a System Engineer]]></description>
        <link>https://blog.siamstr.com/tag/lowlevel/</link>
        <atom:link href="https://blog.siamstr.com/tag/lowlevel/rss/" rel="self" type="application/rss+xml"/>
        <itunes:new-feed-url>https://blog.siamstr.com/tag/lowlevel/rss/</itunes:new-feed-url>
        <itunes:author><![CDATA[VΔz]]></itunes:author>
        <itunes:subtitle><![CDATA[Random thought of a System Engineer]]></itunes:subtitle>
        <itunes:type>episodic</itunes:type>
        <itunes:owner>
          <itunes:name><![CDATA[VΔz]]></itunes:name>
          <itunes:email><![CDATA[VΔz]]></itunes:email>
        </itunes:owner>
            
      <pubDate>Mon, 05 Aug 2024 05:46:34 GMT</pubDate>
      <lastBuildDate>Mon, 05 Aug 2024 05:46:34 GMT</lastBuildDate>
      
      <itunes:image href="https://image.nostr.build/ba269bb842d8e1c6ada4ea3f9203aa570f1610cceeaca6a35c281f28274a914a.jpg" />
      <image>
        <title><![CDATA[Block of Vaz]]></title>
        <link>https://blog.siamstr.com/tag/lowlevel/</link>
        <url>https://image.nostr.build/ba269bb842d8e1c6ada4ea3f9203aa570f1610cceeaca6a35c281f28274a914a.jpg</url>
      </image>
      <item>
      <title><![CDATA[Digging low-level : Bitwise Operation ทำงานอย่างไร?]]></title>
      <description><![CDATA[Bitwise Operations เป็นเครื่องมือที่ทรงพลังสำหรับนักพัฒนาที่ต้องการประสิทธิภาพสูงและการควบคุมระดับบิต โดยเฉพาะในการพัฒนาระบบระดับ low-level และการทำงานกับฮาร์ดแวร์โดยตรง]]></description>
             <itunes:subtitle><![CDATA[Bitwise Operations เป็นเครื่องมือที่ทรงพลังสำหรับนักพัฒนาที่ต้องการประสิทธิภาพสูงและการควบคุมระดับบิต โดยเฉพาะในการพัฒนาระบบระดับ low-level และการทำงานกับฮาร์ดแวร์โดยตรง]]></itunes:subtitle>
      <pubDate>Mon, 05 Aug 2024 05:46:34 GMT</pubDate>
      <link>https://blog.siamstr.com/post/fgriwwzgw2fdmqj5tsjqu/</link>
      <comments>https://blog.siamstr.com/post/fgriwwzgw2fdmqj5tsjqu/</comments>
      <guid isPermaLink="false">naddr1qq25ve6jf9t4wkj82ueyv3rdw99r24rndfch2q3qvaz88a5zhsqsrj220vh5vdnpjsu53msm34hzvcrh27x5d7zeav7qxpqqqp65wfv7942</guid>
      <category>#siamstr</category>
      
        <media:content url="https://www.researchgate.net/profile/Rama_M_A/publication/276202732/figure/fig3/AS:667718365749268@1536207872972/Bitwise-Operators-i-Bitwise-operators-cannot-be-applied-to-float-or-double-They-can.png" medium="image"/>
        <enclosure 
          url="https://www.researchgate.net/profile/Rama_M_A/publication/276202732/figure/fig3/AS:667718365749268@1536207872972/Bitwise-Operators-i-Bitwise-operators-cannot-be-applied-to-float-or-double-They-can.png" length="0" 
          type="image/png" 
        />
      <noteId>naddr1qq25ve6jf9t4wkj82ueyv3rdw99r24rndfch2q3qvaz88a5zhsqsrj220vh5vdnpjsu53msm34hzvcrh27x5d7zeav7qxpqqqp65wfv7942</noteId>
      <npub>npub1vaz88a5zhsqsrj220vh5vdnpjsu53msm34hzvcrh27x5d7zeav7qm45t60</npub>
      <dc:creator><![CDATA[VΔz]]></dc:creator>
      <content:encoded><![CDATA[<blockquote>
<p>Bitwise Operation คือ กระบวนการที่การดำเนินการใด ๆ โดยตรงกับบิตของตัวเลข หรือชุดข้อมูลของเราใน memory  ซึ่งการทำงานโดยตรงกับบิตของตัวเลข ทำให้มีประสิทธิภาพสูงและใช้บ่อยในการเขียนโปรแกรมระดับ low-level  โดยหลัก ๆ ที่ใช้กันจะมี 6 แบบ<br> เป็นเครื่องมือที่ทรงพลังสำหรับนักพัฒนาที่ต้องการประสิทธิภาพสูงและการควบคุมระดับบิต โดยเฉพาะในการพัฒนาระบบระดับ low-level และการทำงานกับฮาร์ดแวร์โดยตรง </p>
</blockquote>
<h2>TLDR</h2>
<p>ภาพรวม Bitwise Operations:</p>
<p>AND (&amp;):</p>
<p>ใช้เปรียบเทียบบิต, ให้ 1 เมื่อทั้งสองบิตเป็น 1<br>ประโยชน์: ตรวจสอบบิต, สร้าง mask</p>
<p>OR (|):</p>
<p>ให้ 1 เมื่อมีบิตใดบิตหนึ่งเป็น 1<br>ประโยชน์: รวมแฟล็ก, ตั้งค่าบิต</p>
<p>XOR (^):</p>
<p>ให้ 1 เมื่อบิตต่างกัน<br>ประโยชน์: สลับค่า, เข้ารหัสอย่างง่าย</p>
<p>NOT (~):</p>
<p>กลับค่าทุกบิต<br>ประโยชน์: สร้าง mask สำหรับลบบิต</p>
<p>Left Shift (&lt;&lt;):</p>
<p>เลื่อนบิตไปซ้าย, เติม 0 ทางขวา<br>ประโยชน์: คูณด้วยกำลังของ 2, สร้าง mask</p>
<p>Right Shift (&gt;&gt;):</p>
<p>เลื่อนบิตไปขวา<br>ประโยชน์: หารด้วยกำลังของ 2, แยกส่วนข้อมูล</p>
<h2>1.) BitAnd (&amp;):</h2>
<p>BitAnd มักใช้สัญลักษณ์ &amp; เป็นการดำเนินการทางตรรกะที่เปรียบเทียบบิตในตำแหน่งเดียวกันของสองตัวเลข โดยมีกฎดังนี้:</p>
<ul>
<li>1 AND 1 = 1</li>
<li>1 AND 0 = 0</li>
<li>0 AND 1 = 0</li>
<li>0 AND 0 = 0</li>
</ul>
<p>หรือกล่าวอีกนัยหนึ่ง ผลลัพธ์จะเป็น 1 ก็ต่อเมื่อทั้งสองบิตเป็น 1 เท่านั้น</p>
<p>ตัวอย่าง:<br>สมมติว่าเรามีเลขสองตัว A = 5 และ B = 3<br>ในระบบเลขฐานสอง:<br>A = 5 = 0101<br>B = 3 = 0011</p>
<p>เมื่อทำ BitAnd:</p>
<pre><code>  0101 (A = 5)
&amp; 0011 (B = 3)
  ----
  0001 (Result = 1)
</code></pre>
<p>จะเห็นได้ว่า:</p>
<ul>
<li>บิตที่ 1 (จากขวา): 1 &amp; 1 = 1</li>
<li>บิตที่ 2: 0 &amp; 1 = 0</li>
<li>บิตที่ 3: 1 &amp; 0 = 0</li>
<li>บิตที่ 4: 0 &amp; 0 = 0</li>
</ul>
<p>ดังนั้น ผลลัพธ์คือ 0001 ในเลขฐานสอง ซึ่งเท่ากับ 1 ในเลขฐานสิบ</p>
<p>การใช้งาน BitAnd:</p>
<ol>
<li><p>การตรวจสอบเลขคู่/คี่:<br>ถ้า (n &amp; 1) == 0 แสดงว่า n เป็นเลขคู่<br>ถ้า (n &amp; 1) == 1 แสดงว่า n เป็นเลขคี่</p>
</li>
<li><p>การตรวจสอบสถานะของบิตเฉพาะ:<br>ถ้าต้องการตรวจสอบบิตที่ 3 ของ x:<br>if (x &amp; (1 &lt;&lt; 2)) != 0 // บิตที่ 3 เป็น 1</p>
</li>
<li><p>การลบบิตสุดท้ายที่เป็น 1:<br>n = n &amp; (n - 1)</p>
</li>
</ol>
<p>BitAnd มีประโยชน์มากในการจัดการกับข้อมูลระดับบิต การตั้งค่าแฟล็ก และการทำงานกับฮาร์ดแวร์โดยตรง</p>
<h2>2.) BitOr (|):</h2>
<p>BitOr มักใช้สัญลักษณ์ | เป็นการดำเนินการทางตรรกะที่เปรียบเทียบบิตในตำแหน่งเดียวกันของสองตัวเลข โดยมีกฎดังนี้:</p>
<ul>
<li>1 OR 1 = 1</li>
<li>1 OR 0 = 1</li>
<li>0 OR 1 = 1</li>
<li>0 OR 0 = 0</li>
</ul>
<p>กล่าวคือ ผลลัพธ์จะเป็น 1 เมื่อมีบิตใดบิตหนึ่งเป็น 1 หรือทั้งสองบิตเป็น 1</p>
<p>ตัวอย่าง:<br>สมมติว่าเรามีเลขสองตัว A = 5 และ B = 3<br>ในระบบเลขฐานสอง:<br>A = 5 = 0101<br>B = 3 = 0011</p>
<p>เมื่อทำ BitOr:</p>
<pre><code>  0101 (A = 5)
| 0011 (B = 3)
  ----
  0111 (Result = 7)
</code></pre>
<p>จะเห็นได้ว่า:</p>
<ul>
<li>บิตที่ 1 (จากขวา): 1 | 1 = 1</li>
<li>บิตที่ 2: 0 | 1 = 1</li>
<li>บิตที่ 3: 1 | 0 = 1</li>
<li>บิตที่ 4: 0 | 0 = 0</li>
</ul>
<p>ดังนั้น ผลลัพธ์คือ 0111 ในเลขฐานสอง ซึ่งเท่ากับ 7 ในเลขฐานสิบ</p>
<p>การใช้งาน BitOr:</p>
<ol>
<li><p>การรวมแฟล็ก:<br>เช่น ในการตั้งค่าสิทธิ์ไฟล์ในระบบ Unix<br>permissions = READ | WRITE | EXECUTE</p>
</li>
<li><p>การตั้งค่าบิตเฉพาะ:<br>ถ้าต้องการตั้งค่าบิตที่ 3 ของ x เป็น 1:<br>x = x | (1 &lt;&lt; 2)</p>
</li>
<li><p>การรวมสี RGB:<br>ในระบบสี RGB ที่ใช้ 8 บิตต่อสี<br>color = (red &lt;&lt; 16) | (green &lt;&lt; 8) | blue</p>
</li>
</ol>
<p>BitOr มีประโยชน์มากในการรวมแฟล็ก การตั้งค่าบิต และการทำงานกับข้อมูลที่แต่ละบิตมีความหมายเฉพาะ</p>
<h2>BitXor (^):</h2>
<p>BitXor หรือ Exclusive OR (XOR) มักใช้สัญลักษณ์ ^ เป็นการดำเนินการทางตรรกะที่เปรียบเทียบบิตในตำแหน่งเดียวกันของสองตัวเลข โดยมีกฎดังนี้:</p>
<ul>
<li>1 XOR 1 = 0</li>
<li>1 XOR 0 = 1</li>
<li>0 XOR 1 = 1</li>
<li>0 XOR 0 = 0</li>
</ul>
<p>กล่าวคือ ผลลัพธ์จะเป็น 1 เมื่อบิตทั้งสองมีค่าต่างกัน</p>
<p>ตัวอย่าง:<br>สมมติว่าเรามีเลขสองตัว A = 5 และ B = 3<br>ในระบบเลขฐานสอง:<br>A = 5 = 0101<br>B = 3 = 0011</p>
<p>เมื่อทำ BitXor:</p>
<pre><code>  0101 (A = 5)
^ 0011 (B = 3)
  ----
  0110 (Result = 6)
</code></pre>
<p>จะเห็นได้ว่า:</p>
<ul>
<li>บิตที่ 1 (จากขวา): 1 ^ 1 = 0</li>
<li>บิตที่ 2: 0 ^ 1 = 1</li>
<li>บิตที่ 3: 1 ^ 0 = 1</li>
<li>บิตที่ 4: 0 ^ 0 = 0</li>
</ul>
<p>ดังนั้น ผลลัพธ์คือ 0110 ในเลขฐานสอง ซึ่งเท่ากับ 6 ในเลขฐานสิบ</p>
<p>การใช้งาน BitXor:</p>
<ol>
<li><p>การสลับค่าโดยไม่ใช้ตัวแปรเพิ่ม:<br>a ^= b;<br>b ^= a;<br>a ^= b;<br>// ตอนนี้ a และ b ได้สลับค่ากันแล้ว</p>
</li>
<li><p>การเข้ารหัสอย่างง่าย:<br>encrypted = data ^ key<br>decrypted = encrypted ^ key  // จะได้ data กลับคืนมา</p>
</li>
<li><p>การตรวจสอบความเท่ากันของตัวเลข:<br>if ((a ^ b) == 0) // a และ b เท่ากัน</p>
</li>
<li><p>การหาตัวเลขที่ไม่มีคู่ในชุดข้อมูล:<br>result = num1 ^ num2 ^ num3 ^ ... // ผลลัพธ์จะเป็นตัวเลขที่ไม่มีคู่</p>
</li>
</ol>
<p>BitXor มีคุณสมบัติพิเศษคือ การ XOR กับตัวเองจะได้ 0 และการ XOR กับ 0 จะได้ตัวเองกลับคืนมา ทำให้มันมีประโยชน์มากในการเข้ารหัสและการตรวจสอบข้อมูล</p>
<h2>BitNot (~):</h2>
<p>BitNot หรือ NOT  มักใช้สัญลักษณ์ ~ เป็นการดำเนินการทางตรรกะที่กลับบิตของตัวเลข โดยมีกฎง่ายๆ คือ:</p>
<ul>
<li>NOT 1 = 0</li>
<li>NOT 0 = 1</li>
</ul>
<p>กล่าวคือ BitNot จะเปลี่ยนทุกบิต 0 เป็น 1 และทุกบิต 1 เป็น 0</p>
<p>ตัวอย่าง:<br>สมมติว่าเรามีเลข A = 5<br>ในระบบเลขฐานสอง (สมมติว่าเป็นเลข 8 บิต):<br>A = 5 = 00000101</p>
<p>เมื่อทำ BitNot:</p>
<pre><code>  00000101 (A = 5)
  --------
~ 11111010 (Result = 250 ใน unsigned int, หรือ -6 ใน signed int)
</code></pre>
<p>จะเห็นได้ว่า:</p>
<ul>
<li>ทุกบิต 0 ถูกเปลี่ยนเป็น 1</li>
<li>ทุกบิต 1 ถูกเปลี่ยนเป็น 0</li>
</ul>
<p>ผลลัพธ์จะขึ้นอยู่กับว่าเราใช้ระบบเลขแบบไหน (signed หรือ unsigned):</p>
<ul>
<li>ในระบบ unsigned 8 บิต: 11111010 = 250</li>
<li>ในระบบ signed 8 บิต: 11111010 = -6</li>
</ul>
<p>การใช้งาน BitNot:</p>
<ol>
<li><p>การสร้าง mask สำหรับการลบบิต:<br>clear_mask = ~(1 &lt;&lt; n)  // สร้าง mask ที่มีบิตที่ n เป็น 0 และที่เหลือเป็น 1<br>x &amp;= clear_mask  // ลบบิตที่ n ของ x</p>
</li>
<li><p>การหาค่าสัมบูรณ์ของเลขติดลบในระบบ two's complement:<br>abs_value = (x ^ (x &gt;&gt; 31)) - (x &gt;&gt; 31)<br>// x &gt;&gt; 31 จะได้ 0 สำหรับเลขบวก และ -1 สำหรับเลขลบ</p>
</li>
<li><p>การสลับสถานะของทุกบิต:<br>inverted = ~original</p>
</li>
<li><p>การหาค่าสูงสุดของตัวแปรที่มีขนาด n บิต:<br>max_value = ~0 &gt;&gt; (32 - n)  // สำหรับตัวแปร 32 บิต</p>
</li>
</ol>
<p>BitNot มักใช้ร่วมกับ BitAnd เพื่อลบบิตที่ต้องการ หรือใช้ในการสร้าง mask สำหรับการจัดการบิต</p>
<h2>Left Shift (&lt;&lt;):</h2>
<p>Left Shift มักใช้สัญลักษณ์ &lt;&lt; เป็นการดำเนินการที่เลื่อนบิตทั้งหมดของตัวเลขไปทางซ้ายตามจำนวนที่กำหนด โดยเติม 0 ทางด้านขวา<br>Left Shift โดยทั่วไปแล้วไม่แตกต่างกันระหว่างเลข unsigned int และ signed int แต่มีบางประเด็นที่ควรระวัง:</p>
<ol>
<li><p>ผลลัพธ์:</p>
<ul>
<li>ในกรณีของเลขไม่มีเครื่องหมาย ผลลัพธ์จะเป็นบวกเสมอ</li>
<li>สำหรับเลขมีเครื่องหมาย ผลลัพธ์อาจเปลี่ยนเครื่องหมายได้หากบิตเครื่องหมาย (sign bit) ถูกเปลี่ยน</li>
</ul>
</li>
<li><p>Overflow:</p>
<ul>
<li>ทั้งสองกรณีอาจเกิด overflow ได้ถ้าเลื่อนมากเกินไป</li>
<li>สำหรับเลข signed int overflow อาจทำให้เกิดการเปลี่ยนเครื่องหมายโดยไม่คาดคิด</li>
</ul>
</li>
<li><p>Undefined Behavior:</p>
<ul>
<li>ในบางภาษา เช่น C/C++, การเลื่อนด้วยค่าที่มากกว่าหรือเท่ากับจำนวนบิตของตัวแปรอาจทำให้เกิด Undefined Behavior ได้</li>
</ul>
</li>
</ol>
<p>ตัวอย่าง:<br>สมมติว่าเรามีเลข A = 5 และต้องการเลื่อนซ้าย 2 ตำแหน่ง<br>ในระบบเลขฐานสอง (สมมติว่าเป็นเลข 8 บิต):<br>A = 5 = 00000101</p>
<p>เมื่อทำ Left Shift 2 ตำแหน่ง (A &lt;&lt; 2):</p>
<pre><code>  00000101 (A = 5)
  --------
  00010100 (Result = 20)
</code></pre>
<p>จะเห็นได้ว่า::</p>
<ul>
<li>บิตทั้งหมดถูกเลื่อนไปทางซ้าย 2 ตำแหน่ง</li>
<li>เติม 0 สองตัวทางด้านขวา</li>
</ul>
<p>ผลลัพธ์: 00010100 ในเลขฐานสอง ซึ่งเท่ากับ 20 ในเลขฐานสิบ</p>
<p>ตัวอย่าง 2:</p>
<pre><code>unsigned int a = 1;  // 00000001 in binary
int b = 1;           // 00000001 in binary

// Left shift by 3
unsigned int a_result = a &lt;&lt; 3;  // 00001000 (8 in decimal)
int b_result = b &lt;&lt; 3;           // 00001000 (8 in decimal)

// สำหรับตัวเลขเล็ก ๆ ผลอาจจะไม่ต่างกัน
// แต่เมื่อมีตัวเลขที่ใหญ่ขึ้น อาจจะให้ผลตรงกันข้ามแทน:

unsigned int large_a = 1 &lt;&lt; 31;  // 10000000 00000000 00000000 00000000 (2147483648 in decimal)
int large_b = 1 &lt;&lt; 31;           // 10000000 00000000 00000000 00000000 (-2147483648 in decimal, due to two's complement)
</code></pre>
<p>ในตัวอย่างสุดท้าย เราเห็นความแตกต่าง:</p>
<ul>
<li>สำหรับ unsigned int, ผลลัพธ์คือเลขบวกที่ใหญ่ที่สุดที่เป็นไปได้</li>
<li>สำหรับ signed int, ผลลัพธ์คือเลขลบที่น้อยที่สุดที่เป็นไปได้ เนื่องจากบิตซ้ายสุดถูกตีความเป็นเครื่องหมายลบในระบบ two's complement</li>
</ul>
<p>กฎการทำงาน:</p>
<ul>
<li>เลื่อนบิตทั้งหมดไปทางซ้าย n ตำแหน่ง</li>
<li>เติม 0 ทางด้านขวา n ตัว</li>
<li>บิตที่เลื่อนออกไปทางซ้ายจะหายไป</li>
</ul>
<p>การใช้งาน Left Shift:</p>
<ol>
<li><p>การคูณด้วยกำลังของ 2:<br>x &lt;&lt; n เท่ากับ x * (2^n)<br>เช่น 5 &lt;&lt; 2 = 5 * (2^2) = 5 * 4 = 20</p>
</li>
<li><p>การสร้างหน้ากาก (mask) สำหรับการตั้งค่าบิต:<br>mask = 1 &lt;&lt; n  // สร้างหน้ากากที่มีบิตที่ n เป็น 1 และที่เหลือเป็น 0<br>x |= mask  // ตั้งค่าบิตที่ n ของ x เป็น 1</p>
</li>
<li><p>การเข้ารหัสข้อมูลหลายบิตในตัวแปรเดียว:<br>encoded = (r &lt;&lt; 16) | (g &lt;&lt; 8) | b  // เก็บค่า RGB ในตัวแปร 32 บิต</p>
</li>
<li><p>การทำงานกับบิตแฟล็ก:<br>FLAG_A = 1 &lt;&lt; 0<br>FLAG_B = 1 &lt;&lt; 1<br>FLAG_C = 1 &lt;&lt; 2<br>// ใช้งาน: flags = FLAG_A | FLAG_B</p>
</li>
</ol>
<p>Left Shift มีประสิทธิภาพสูงในการคูณด้วยกำลังของ 2 และมักใช้ในการจัดการบิตแฟล็กและการสร้างหน้ากากสำหรับการดำเนินการระดับบิต</p>
<h2>Right Shift (&gt;&gt;):</h2>
<p>Right Shift มักใช้สัญลักษณ์ &gt;&gt; เป็นการดำเนินการที่เลื่อนบิตทั้งหมดของตัวเลขไปทางขวาตามจำนวนที่กำหนด การทำงานจะแตกต่างกันเล็กน้อยระหว่างเลขที่มีเครื่องหมาย (signed) และไม่มีเครื่องหมาย (unsigned)</p>
<p>สำหรับเลข unsigned int (Logical Right Shift):</p>
<ul>
<li>เลื่อนบิตทั้งหมดไปทางขวา n ตำแหน่ง</li>
<li>เติม 0 ทางด้านซ้าย n ตัว</li>
<li>บิตที่เลื่อนออกไปทางขวาจะหายไป</li>
</ul>
<p>สำหรับเลข signed int (Arithmetic Right Shift):</p>
<ul>
<li>เลื่อนบิตทั้งหมดไปทางขวา n ตำแหน่ง</li>
<li>เติมด้วยบิตเครื่องหมาย (sign bit) ทางด้านซ้าย n ตัว</li>
<li>บิตที่เลื่อนออกไปทางขวาจะหายไป</li>
</ul>
<p>ตัวอย่าง:<br>สมมติว่าเรามีเลข A = 20 และต้องการเลื่อนขวา 2 ตำแหน่ง<br>ในระบบเลขฐานสอง (สมมติว่าเป็นเลข 8 บิต):<br>A = 20 = 00010100</p>
<p>เมื่อทำ Right Shift 2 ตำแหน่ง (A &gt;&gt; 2):</p>
<pre><code>  00010100 (A = 20)
  --------
  00000101 (Result = 5)
</code></pre>
<p>จะเห็นได้ว่า::</p>
<ul>
<li>บิตทั้งหมดถูกเลื่อนไปทางขวา 2 ตำแหน่ง</li>
<li>เติม 0 สองตัวทางด้านซ้าย (สำหรับเลขไม่มีเครื่องหมาย)</li>
</ul>
<p>ผลลัพธ์: 00000101 ในเลขฐานสอง ซึ่งเท่ากับ 5 ในเลขฐานสิบ</p>
<p>การใช้งาน Right Shift:</p>
<ol>
<li><p>การหารด้วยกำลังของ 2:<br>x &gt;&gt; n เท่ากับ x / (2^n) (ปัดเศษลง)<br>เช่น 20 &gt;&gt; 2 = 20 / (2^2) = 20 / 4 = 5</p>
</li>
<li><p>การแยกส่วนของข้อมูลที่ถูกเก็บรวมกัน:<br>r = (rgb &gt;&gt; 16) &amp; 0xFF  // แยกค่าสีแดงจาก RGB 24 บิต<br>g = (rgb &gt;&gt; 8) &amp; 0xFF   // แยกค่าสีเขียว<br>b = rgb &amp; 0xFF          // แยกค่าสีน้ำเงิน</p>
</li>
<li><p>การตรวจสอบเครื่องหมายของตัวเลข:<br>sign = x &gt;&gt; 31  // สำหรับตัวแปร 32 บิต, จะได้ 0 สำหรับบวก และ -1 สำหรับลบ</p>
</li>
<li><p>การทำ rounded division:<br>(x + (1 &lt;&lt; (n-1))) &gt;&gt; n  // หารด้วย 2^n และปัดเศษ</p>
</li>
</ol>
<p>ข้อควรระวัง:</p>
<ul>
<li>ใน Java, &gt;&gt; เป็น arithmetic shift สำหรับ int และ long, ส่วน &gt;&gt;&gt; เป็น logical shift</li>
<li>ในภาษาอื่นๆ เช่น C/C++, การทำงานของ &gt;&gt; กับเลขติดลบอาจแตกต่างกันไปตาม Compiler</li>
</ul>
<p>Right Shift มีประสิทธิภาพสูงในการหารด้วยกำลังของ 2 และมักใช้ในการจัดการข้อมูลที่ถูกเก็บรวมกันในรูปแบบบิต</p>
<p>หากเปรียบกับ Right Shift แม้ว่าการทำงานพื้นฐานของ Left Shift จะเหมือนกันสำหรับทั้งเลข signed int และ unsigned int แต่การตีความผลลัพธ์และผลกระทบต่อเครื่องหมาย(sign bit)อาจแตกต่างกัน ดังนั้นจึงควรระมัดระวังเมื่อใช้ Left Shift กับเลขที่มี signed int โดยเฉพาะเมื่อเลื่อนด้วยค่าที่สูงมาก ๆ</p>
<h2>Conclusion</h2>
<h4>ลักษณะเด่นของ Bitwise Operations:</h4>
<ul>
<li>ประสิทธิภาพสูง: ทำงานเร็วกว่าการคำนวณปกติ</li>
<li>ประหยัดหน่วยความจำ: จัดเก็บข้อมูลหลายอย่างในตัวแปรเดียว</li>
<li>ใช้ในงานระดับต่ำ: การทำงานกับฮาร์ดแวร์, ระบบปฏิบัติการ</li>
<li>การเข้ารหัส: ใช้ในอัลกอริทึมการเข้ารหัสและบีบอัดข้อมูล</li>
<li>การจัดการแฟล็ก: ใช้ในการตั้งค่าและตรวจสอบสถานะต่างๆ</li>
</ul>
<h4>การใช้งานทั่วไป:</h4>
<ul>
<li>จัดการสิทธิ์และการอนุญาตในระบบไฟล์</li>
<li>การเข้ารหัสและถอดรหัสข้อมูล</li>
<li>การบีบอัดข้อมูล</li>
<li>การทำงานกับพิกเซลในการประมวลผลภาพ</li>
<li>การจัดการโปรโตคอลเครือข่าย</li>
<li>การทำงานกับ register ใน Embedded system</li>
</ul>
<h4>ข้อควรระวัง:</h4>
<ul>
<li>ต้องระมัดระวังเรื่องขนาดของข้อมูล (8, 16, 32, 64 บิต)</li>
<li>ความแตกต่างระหว่างเลขมี signed int และ unsigned int</li>
<li>ความแตกต่างของการทำงานในแต่ละภาษาโปรแกรม</li>
</ul>
<p>**unsigned int คือตัวเลขเป็นบวกเสมอ signed int สามารถมีค่าเป็นลบได้</p>
<p>#siamstr #Blog</p>
]]></content:encoded>
      <itunes:author><![CDATA[VΔz]]></itunes:author>
      <itunes:summary><![CDATA[<blockquote>
<p>Bitwise Operation คือ กระบวนการที่การดำเนินการใด ๆ โดยตรงกับบิตของตัวเลข หรือชุดข้อมูลของเราใน memory  ซึ่งการทำงานโดยตรงกับบิตของตัวเลข ทำให้มีประสิทธิภาพสูงและใช้บ่อยในการเขียนโปรแกรมระดับ low-level  โดยหลัก ๆ ที่ใช้กันจะมี 6 แบบ<br> เป็นเครื่องมือที่ทรงพลังสำหรับนักพัฒนาที่ต้องการประสิทธิภาพสูงและการควบคุมระดับบิต โดยเฉพาะในการพัฒนาระบบระดับ low-level และการทำงานกับฮาร์ดแวร์โดยตรง </p>
</blockquote>
<h2>TLDR</h2>
<p>ภาพรวม Bitwise Operations:</p>
<p>AND (&amp;):</p>
<p>ใช้เปรียบเทียบบิต, ให้ 1 เมื่อทั้งสองบิตเป็น 1<br>ประโยชน์: ตรวจสอบบิต, สร้าง mask</p>
<p>OR (|):</p>
<p>ให้ 1 เมื่อมีบิตใดบิตหนึ่งเป็น 1<br>ประโยชน์: รวมแฟล็ก, ตั้งค่าบิต</p>
<p>XOR (^):</p>
<p>ให้ 1 เมื่อบิตต่างกัน<br>ประโยชน์: สลับค่า, เข้ารหัสอย่างง่าย</p>
<p>NOT (~):</p>
<p>กลับค่าทุกบิต<br>ประโยชน์: สร้าง mask สำหรับลบบิต</p>
<p>Left Shift (&lt;&lt;):</p>
<p>เลื่อนบิตไปซ้าย, เติม 0 ทางขวา<br>ประโยชน์: คูณด้วยกำลังของ 2, สร้าง mask</p>
<p>Right Shift (&gt;&gt;):</p>
<p>เลื่อนบิตไปขวา<br>ประโยชน์: หารด้วยกำลังของ 2, แยกส่วนข้อมูล</p>
<h2>1.) BitAnd (&amp;):</h2>
<p>BitAnd มักใช้สัญลักษณ์ &amp; เป็นการดำเนินการทางตรรกะที่เปรียบเทียบบิตในตำแหน่งเดียวกันของสองตัวเลข โดยมีกฎดังนี้:</p>
<ul>
<li>1 AND 1 = 1</li>
<li>1 AND 0 = 0</li>
<li>0 AND 1 = 0</li>
<li>0 AND 0 = 0</li>
</ul>
<p>หรือกล่าวอีกนัยหนึ่ง ผลลัพธ์จะเป็น 1 ก็ต่อเมื่อทั้งสองบิตเป็น 1 เท่านั้น</p>
<p>ตัวอย่าง:<br>สมมติว่าเรามีเลขสองตัว A = 5 และ B = 3<br>ในระบบเลขฐานสอง:<br>A = 5 = 0101<br>B = 3 = 0011</p>
<p>เมื่อทำ BitAnd:</p>
<pre><code>  0101 (A = 5)
&amp; 0011 (B = 3)
  ----
  0001 (Result = 1)
</code></pre>
<p>จะเห็นได้ว่า:</p>
<ul>
<li>บิตที่ 1 (จากขวา): 1 &amp; 1 = 1</li>
<li>บิตที่ 2: 0 &amp; 1 = 0</li>
<li>บิตที่ 3: 1 &amp; 0 = 0</li>
<li>บิตที่ 4: 0 &amp; 0 = 0</li>
</ul>
<p>ดังนั้น ผลลัพธ์คือ 0001 ในเลขฐานสอง ซึ่งเท่ากับ 1 ในเลขฐานสิบ</p>
<p>การใช้งาน BitAnd:</p>
<ol>
<li><p>การตรวจสอบเลขคู่/คี่:<br>ถ้า (n &amp; 1) == 0 แสดงว่า n เป็นเลขคู่<br>ถ้า (n &amp; 1) == 1 แสดงว่า n เป็นเลขคี่</p>
</li>
<li><p>การตรวจสอบสถานะของบิตเฉพาะ:<br>ถ้าต้องการตรวจสอบบิตที่ 3 ของ x:<br>if (x &amp; (1 &lt;&lt; 2)) != 0 // บิตที่ 3 เป็น 1</p>
</li>
<li><p>การลบบิตสุดท้ายที่เป็น 1:<br>n = n &amp; (n - 1)</p>
</li>
</ol>
<p>BitAnd มีประโยชน์มากในการจัดการกับข้อมูลระดับบิต การตั้งค่าแฟล็ก และการทำงานกับฮาร์ดแวร์โดยตรง</p>
<h2>2.) BitOr (|):</h2>
<p>BitOr มักใช้สัญลักษณ์ | เป็นการดำเนินการทางตรรกะที่เปรียบเทียบบิตในตำแหน่งเดียวกันของสองตัวเลข โดยมีกฎดังนี้:</p>
<ul>
<li>1 OR 1 = 1</li>
<li>1 OR 0 = 1</li>
<li>0 OR 1 = 1</li>
<li>0 OR 0 = 0</li>
</ul>
<p>กล่าวคือ ผลลัพธ์จะเป็น 1 เมื่อมีบิตใดบิตหนึ่งเป็น 1 หรือทั้งสองบิตเป็น 1</p>
<p>ตัวอย่าง:<br>สมมติว่าเรามีเลขสองตัว A = 5 และ B = 3<br>ในระบบเลขฐานสอง:<br>A = 5 = 0101<br>B = 3 = 0011</p>
<p>เมื่อทำ BitOr:</p>
<pre><code>  0101 (A = 5)
| 0011 (B = 3)
  ----
  0111 (Result = 7)
</code></pre>
<p>จะเห็นได้ว่า:</p>
<ul>
<li>บิตที่ 1 (จากขวา): 1 | 1 = 1</li>
<li>บิตที่ 2: 0 | 1 = 1</li>
<li>บิตที่ 3: 1 | 0 = 1</li>
<li>บิตที่ 4: 0 | 0 = 0</li>
</ul>
<p>ดังนั้น ผลลัพธ์คือ 0111 ในเลขฐานสอง ซึ่งเท่ากับ 7 ในเลขฐานสิบ</p>
<p>การใช้งาน BitOr:</p>
<ol>
<li><p>การรวมแฟล็ก:<br>เช่น ในการตั้งค่าสิทธิ์ไฟล์ในระบบ Unix<br>permissions = READ | WRITE | EXECUTE</p>
</li>
<li><p>การตั้งค่าบิตเฉพาะ:<br>ถ้าต้องการตั้งค่าบิตที่ 3 ของ x เป็น 1:<br>x = x | (1 &lt;&lt; 2)</p>
</li>
<li><p>การรวมสี RGB:<br>ในระบบสี RGB ที่ใช้ 8 บิตต่อสี<br>color = (red &lt;&lt; 16) | (green &lt;&lt; 8) | blue</p>
</li>
</ol>
<p>BitOr มีประโยชน์มากในการรวมแฟล็ก การตั้งค่าบิต และการทำงานกับข้อมูลที่แต่ละบิตมีความหมายเฉพาะ</p>
<h2>BitXor (^):</h2>
<p>BitXor หรือ Exclusive OR (XOR) มักใช้สัญลักษณ์ ^ เป็นการดำเนินการทางตรรกะที่เปรียบเทียบบิตในตำแหน่งเดียวกันของสองตัวเลข โดยมีกฎดังนี้:</p>
<ul>
<li>1 XOR 1 = 0</li>
<li>1 XOR 0 = 1</li>
<li>0 XOR 1 = 1</li>
<li>0 XOR 0 = 0</li>
</ul>
<p>กล่าวคือ ผลลัพธ์จะเป็น 1 เมื่อบิตทั้งสองมีค่าต่างกัน</p>
<p>ตัวอย่าง:<br>สมมติว่าเรามีเลขสองตัว A = 5 และ B = 3<br>ในระบบเลขฐานสอง:<br>A = 5 = 0101<br>B = 3 = 0011</p>
<p>เมื่อทำ BitXor:</p>
<pre><code>  0101 (A = 5)
^ 0011 (B = 3)
  ----
  0110 (Result = 6)
</code></pre>
<p>จะเห็นได้ว่า:</p>
<ul>
<li>บิตที่ 1 (จากขวา): 1 ^ 1 = 0</li>
<li>บิตที่ 2: 0 ^ 1 = 1</li>
<li>บิตที่ 3: 1 ^ 0 = 1</li>
<li>บิตที่ 4: 0 ^ 0 = 0</li>
</ul>
<p>ดังนั้น ผลลัพธ์คือ 0110 ในเลขฐานสอง ซึ่งเท่ากับ 6 ในเลขฐานสิบ</p>
<p>การใช้งาน BitXor:</p>
<ol>
<li><p>การสลับค่าโดยไม่ใช้ตัวแปรเพิ่ม:<br>a ^= b;<br>b ^= a;<br>a ^= b;<br>// ตอนนี้ a และ b ได้สลับค่ากันแล้ว</p>
</li>
<li><p>การเข้ารหัสอย่างง่าย:<br>encrypted = data ^ key<br>decrypted = encrypted ^ key  // จะได้ data กลับคืนมา</p>
</li>
<li><p>การตรวจสอบความเท่ากันของตัวเลข:<br>if ((a ^ b) == 0) // a และ b เท่ากัน</p>
</li>
<li><p>การหาตัวเลขที่ไม่มีคู่ในชุดข้อมูล:<br>result = num1 ^ num2 ^ num3 ^ ... // ผลลัพธ์จะเป็นตัวเลขที่ไม่มีคู่</p>
</li>
</ol>
<p>BitXor มีคุณสมบัติพิเศษคือ การ XOR กับตัวเองจะได้ 0 และการ XOR กับ 0 จะได้ตัวเองกลับคืนมา ทำให้มันมีประโยชน์มากในการเข้ารหัสและการตรวจสอบข้อมูล</p>
<h2>BitNot (~):</h2>
<p>BitNot หรือ NOT  มักใช้สัญลักษณ์ ~ เป็นการดำเนินการทางตรรกะที่กลับบิตของตัวเลข โดยมีกฎง่ายๆ คือ:</p>
<ul>
<li>NOT 1 = 0</li>
<li>NOT 0 = 1</li>
</ul>
<p>กล่าวคือ BitNot จะเปลี่ยนทุกบิต 0 เป็น 1 และทุกบิต 1 เป็น 0</p>
<p>ตัวอย่าง:<br>สมมติว่าเรามีเลข A = 5<br>ในระบบเลขฐานสอง (สมมติว่าเป็นเลข 8 บิต):<br>A = 5 = 00000101</p>
<p>เมื่อทำ BitNot:</p>
<pre><code>  00000101 (A = 5)
  --------
~ 11111010 (Result = 250 ใน unsigned int, หรือ -6 ใน signed int)
</code></pre>
<p>จะเห็นได้ว่า:</p>
<ul>
<li>ทุกบิต 0 ถูกเปลี่ยนเป็น 1</li>
<li>ทุกบิต 1 ถูกเปลี่ยนเป็น 0</li>
</ul>
<p>ผลลัพธ์จะขึ้นอยู่กับว่าเราใช้ระบบเลขแบบไหน (signed หรือ unsigned):</p>
<ul>
<li>ในระบบ unsigned 8 บิต: 11111010 = 250</li>
<li>ในระบบ signed 8 บิต: 11111010 = -6</li>
</ul>
<p>การใช้งาน BitNot:</p>
<ol>
<li><p>การสร้าง mask สำหรับการลบบิต:<br>clear_mask = ~(1 &lt;&lt; n)  // สร้าง mask ที่มีบิตที่ n เป็น 0 และที่เหลือเป็น 1<br>x &amp;= clear_mask  // ลบบิตที่ n ของ x</p>
</li>
<li><p>การหาค่าสัมบูรณ์ของเลขติดลบในระบบ two's complement:<br>abs_value = (x ^ (x &gt;&gt; 31)) - (x &gt;&gt; 31)<br>// x &gt;&gt; 31 จะได้ 0 สำหรับเลขบวก และ -1 สำหรับเลขลบ</p>
</li>
<li><p>การสลับสถานะของทุกบิต:<br>inverted = ~original</p>
</li>
<li><p>การหาค่าสูงสุดของตัวแปรที่มีขนาด n บิต:<br>max_value = ~0 &gt;&gt; (32 - n)  // สำหรับตัวแปร 32 บิต</p>
</li>
</ol>
<p>BitNot มักใช้ร่วมกับ BitAnd เพื่อลบบิตที่ต้องการ หรือใช้ในการสร้าง mask สำหรับการจัดการบิต</p>
<h2>Left Shift (&lt;&lt;):</h2>
<p>Left Shift มักใช้สัญลักษณ์ &lt;&lt; เป็นการดำเนินการที่เลื่อนบิตทั้งหมดของตัวเลขไปทางซ้ายตามจำนวนที่กำหนด โดยเติม 0 ทางด้านขวา<br>Left Shift โดยทั่วไปแล้วไม่แตกต่างกันระหว่างเลข unsigned int และ signed int แต่มีบางประเด็นที่ควรระวัง:</p>
<ol>
<li><p>ผลลัพธ์:</p>
<ul>
<li>ในกรณีของเลขไม่มีเครื่องหมาย ผลลัพธ์จะเป็นบวกเสมอ</li>
<li>สำหรับเลขมีเครื่องหมาย ผลลัพธ์อาจเปลี่ยนเครื่องหมายได้หากบิตเครื่องหมาย (sign bit) ถูกเปลี่ยน</li>
</ul>
</li>
<li><p>Overflow:</p>
<ul>
<li>ทั้งสองกรณีอาจเกิด overflow ได้ถ้าเลื่อนมากเกินไป</li>
<li>สำหรับเลข signed int overflow อาจทำให้เกิดการเปลี่ยนเครื่องหมายโดยไม่คาดคิด</li>
</ul>
</li>
<li><p>Undefined Behavior:</p>
<ul>
<li>ในบางภาษา เช่น C/C++, การเลื่อนด้วยค่าที่มากกว่าหรือเท่ากับจำนวนบิตของตัวแปรอาจทำให้เกิด Undefined Behavior ได้</li>
</ul>
</li>
</ol>
<p>ตัวอย่าง:<br>สมมติว่าเรามีเลข A = 5 และต้องการเลื่อนซ้าย 2 ตำแหน่ง<br>ในระบบเลขฐานสอง (สมมติว่าเป็นเลข 8 บิต):<br>A = 5 = 00000101</p>
<p>เมื่อทำ Left Shift 2 ตำแหน่ง (A &lt;&lt; 2):</p>
<pre><code>  00000101 (A = 5)
  --------
  00010100 (Result = 20)
</code></pre>
<p>จะเห็นได้ว่า::</p>
<ul>
<li>บิตทั้งหมดถูกเลื่อนไปทางซ้าย 2 ตำแหน่ง</li>
<li>เติม 0 สองตัวทางด้านขวา</li>
</ul>
<p>ผลลัพธ์: 00010100 ในเลขฐานสอง ซึ่งเท่ากับ 20 ในเลขฐานสิบ</p>
<p>ตัวอย่าง 2:</p>
<pre><code>unsigned int a = 1;  // 00000001 in binary
int b = 1;           // 00000001 in binary

// Left shift by 3
unsigned int a_result = a &lt;&lt; 3;  // 00001000 (8 in decimal)
int b_result = b &lt;&lt; 3;           // 00001000 (8 in decimal)

// สำหรับตัวเลขเล็ก ๆ ผลอาจจะไม่ต่างกัน
// แต่เมื่อมีตัวเลขที่ใหญ่ขึ้น อาจจะให้ผลตรงกันข้ามแทน:

unsigned int large_a = 1 &lt;&lt; 31;  // 10000000 00000000 00000000 00000000 (2147483648 in decimal)
int large_b = 1 &lt;&lt; 31;           // 10000000 00000000 00000000 00000000 (-2147483648 in decimal, due to two's complement)
</code></pre>
<p>ในตัวอย่างสุดท้าย เราเห็นความแตกต่าง:</p>
<ul>
<li>สำหรับ unsigned int, ผลลัพธ์คือเลขบวกที่ใหญ่ที่สุดที่เป็นไปได้</li>
<li>สำหรับ signed int, ผลลัพธ์คือเลขลบที่น้อยที่สุดที่เป็นไปได้ เนื่องจากบิตซ้ายสุดถูกตีความเป็นเครื่องหมายลบในระบบ two's complement</li>
</ul>
<p>กฎการทำงาน:</p>
<ul>
<li>เลื่อนบิตทั้งหมดไปทางซ้าย n ตำแหน่ง</li>
<li>เติม 0 ทางด้านขวา n ตัว</li>
<li>บิตที่เลื่อนออกไปทางซ้ายจะหายไป</li>
</ul>
<p>การใช้งาน Left Shift:</p>
<ol>
<li><p>การคูณด้วยกำลังของ 2:<br>x &lt;&lt; n เท่ากับ x * (2^n)<br>เช่น 5 &lt;&lt; 2 = 5 * (2^2) = 5 * 4 = 20</p>
</li>
<li><p>การสร้างหน้ากาก (mask) สำหรับการตั้งค่าบิต:<br>mask = 1 &lt;&lt; n  // สร้างหน้ากากที่มีบิตที่ n เป็น 1 และที่เหลือเป็น 0<br>x |= mask  // ตั้งค่าบิตที่ n ของ x เป็น 1</p>
</li>
<li><p>การเข้ารหัสข้อมูลหลายบิตในตัวแปรเดียว:<br>encoded = (r &lt;&lt; 16) | (g &lt;&lt; 8) | b  // เก็บค่า RGB ในตัวแปร 32 บิต</p>
</li>
<li><p>การทำงานกับบิตแฟล็ก:<br>FLAG_A = 1 &lt;&lt; 0<br>FLAG_B = 1 &lt;&lt; 1<br>FLAG_C = 1 &lt;&lt; 2<br>// ใช้งาน: flags = FLAG_A | FLAG_B</p>
</li>
</ol>
<p>Left Shift มีประสิทธิภาพสูงในการคูณด้วยกำลังของ 2 และมักใช้ในการจัดการบิตแฟล็กและการสร้างหน้ากากสำหรับการดำเนินการระดับบิต</p>
<h2>Right Shift (&gt;&gt;):</h2>
<p>Right Shift มักใช้สัญลักษณ์ &gt;&gt; เป็นการดำเนินการที่เลื่อนบิตทั้งหมดของตัวเลขไปทางขวาตามจำนวนที่กำหนด การทำงานจะแตกต่างกันเล็กน้อยระหว่างเลขที่มีเครื่องหมาย (signed) และไม่มีเครื่องหมาย (unsigned)</p>
<p>สำหรับเลข unsigned int (Logical Right Shift):</p>
<ul>
<li>เลื่อนบิตทั้งหมดไปทางขวา n ตำแหน่ง</li>
<li>เติม 0 ทางด้านซ้าย n ตัว</li>
<li>บิตที่เลื่อนออกไปทางขวาจะหายไป</li>
</ul>
<p>สำหรับเลข signed int (Arithmetic Right Shift):</p>
<ul>
<li>เลื่อนบิตทั้งหมดไปทางขวา n ตำแหน่ง</li>
<li>เติมด้วยบิตเครื่องหมาย (sign bit) ทางด้านซ้าย n ตัว</li>
<li>บิตที่เลื่อนออกไปทางขวาจะหายไป</li>
</ul>
<p>ตัวอย่าง:<br>สมมติว่าเรามีเลข A = 20 และต้องการเลื่อนขวา 2 ตำแหน่ง<br>ในระบบเลขฐานสอง (สมมติว่าเป็นเลข 8 บิต):<br>A = 20 = 00010100</p>
<p>เมื่อทำ Right Shift 2 ตำแหน่ง (A &gt;&gt; 2):</p>
<pre><code>  00010100 (A = 20)
  --------
  00000101 (Result = 5)
</code></pre>
<p>จะเห็นได้ว่า::</p>
<ul>
<li>บิตทั้งหมดถูกเลื่อนไปทางขวา 2 ตำแหน่ง</li>
<li>เติม 0 สองตัวทางด้านซ้าย (สำหรับเลขไม่มีเครื่องหมาย)</li>
</ul>
<p>ผลลัพธ์: 00000101 ในเลขฐานสอง ซึ่งเท่ากับ 5 ในเลขฐานสิบ</p>
<p>การใช้งาน Right Shift:</p>
<ol>
<li><p>การหารด้วยกำลังของ 2:<br>x &gt;&gt; n เท่ากับ x / (2^n) (ปัดเศษลง)<br>เช่น 20 &gt;&gt; 2 = 20 / (2^2) = 20 / 4 = 5</p>
</li>
<li><p>การแยกส่วนของข้อมูลที่ถูกเก็บรวมกัน:<br>r = (rgb &gt;&gt; 16) &amp; 0xFF  // แยกค่าสีแดงจาก RGB 24 บิต<br>g = (rgb &gt;&gt; 8) &amp; 0xFF   // แยกค่าสีเขียว<br>b = rgb &amp; 0xFF          // แยกค่าสีน้ำเงิน</p>
</li>
<li><p>การตรวจสอบเครื่องหมายของตัวเลข:<br>sign = x &gt;&gt; 31  // สำหรับตัวแปร 32 บิต, จะได้ 0 สำหรับบวก และ -1 สำหรับลบ</p>
</li>
<li><p>การทำ rounded division:<br>(x + (1 &lt;&lt; (n-1))) &gt;&gt; n  // หารด้วย 2^n และปัดเศษ</p>
</li>
</ol>
<p>ข้อควรระวัง:</p>
<ul>
<li>ใน Java, &gt;&gt; เป็น arithmetic shift สำหรับ int และ long, ส่วน &gt;&gt;&gt; เป็น logical shift</li>
<li>ในภาษาอื่นๆ เช่น C/C++, การทำงานของ &gt;&gt; กับเลขติดลบอาจแตกต่างกันไปตาม Compiler</li>
</ul>
<p>Right Shift มีประสิทธิภาพสูงในการหารด้วยกำลังของ 2 และมักใช้ในการจัดการข้อมูลที่ถูกเก็บรวมกันในรูปแบบบิต</p>
<p>หากเปรียบกับ Right Shift แม้ว่าการทำงานพื้นฐานของ Left Shift จะเหมือนกันสำหรับทั้งเลข signed int และ unsigned int แต่การตีความผลลัพธ์และผลกระทบต่อเครื่องหมาย(sign bit)อาจแตกต่างกัน ดังนั้นจึงควรระมัดระวังเมื่อใช้ Left Shift กับเลขที่มี signed int โดยเฉพาะเมื่อเลื่อนด้วยค่าที่สูงมาก ๆ</p>
<h2>Conclusion</h2>
<h4>ลักษณะเด่นของ Bitwise Operations:</h4>
<ul>
<li>ประสิทธิภาพสูง: ทำงานเร็วกว่าการคำนวณปกติ</li>
<li>ประหยัดหน่วยความจำ: จัดเก็บข้อมูลหลายอย่างในตัวแปรเดียว</li>
<li>ใช้ในงานระดับต่ำ: การทำงานกับฮาร์ดแวร์, ระบบปฏิบัติการ</li>
<li>การเข้ารหัส: ใช้ในอัลกอริทึมการเข้ารหัสและบีบอัดข้อมูล</li>
<li>การจัดการแฟล็ก: ใช้ในการตั้งค่าและตรวจสอบสถานะต่างๆ</li>
</ul>
<h4>การใช้งานทั่วไป:</h4>
<ul>
<li>จัดการสิทธิ์และการอนุญาตในระบบไฟล์</li>
<li>การเข้ารหัสและถอดรหัสข้อมูล</li>
<li>การบีบอัดข้อมูล</li>
<li>การทำงานกับพิกเซลในการประมวลผลภาพ</li>
<li>การจัดการโปรโตคอลเครือข่าย</li>
<li>การทำงานกับ register ใน Embedded system</li>
</ul>
<h4>ข้อควรระวัง:</h4>
<ul>
<li>ต้องระมัดระวังเรื่องขนาดของข้อมูล (8, 16, 32, 64 บิต)</li>
<li>ความแตกต่างระหว่างเลขมี signed int และ unsigned int</li>
<li>ความแตกต่างของการทำงานในแต่ละภาษาโปรแกรม</li>
</ul>
<p>**unsigned int คือตัวเลขเป็นบวกเสมอ signed int สามารถมีค่าเป็นลบได้</p>
<p>#siamstr #Blog</p>
]]></itunes:summary>
      <itunes:image href="https://www.researchgate.net/profile/Rama_M_A/publication/276202732/figure/fig3/AS:667718365749268@1536207872972/Bitwise-Operators-i-Bitwise-operators-cannot-be-applied-to-float-or-double-They-can.png"/>
      </item>
      
      </channel>
      </rss>
    