[ჸჸCPP]3.ᄃᄃᄃᄃᄃᄃᄃᄃ

24094 ワード

Created: June 6, 2021 11:22 AM
Tag: bit flag, bit mask, bitwise, logical, operator, relational
3.1演算子優先度および連結ルール
Operators in C and C++ - Wikipedia
3.5関係演算子関係演算子
#include <iostream>
#inlcude <cmath>

int main(void)
{
	using namespace std;

	double d1(100 - 99.99);
	double d2(10 - 9.99);
	if (d1 == d2)
			cout << "eqal" << endl;
	else
	{
		cout << "not equal" << endl;
		if (d1 > d2)
			cout << "d1 > d2" << endl;
		else
			cout << "d1 < d2" << endl;
	}
}

// result
not equal
d1 > d2
💡 浮動小数点は上記の誤差を生じることを示す.これを克服するために,誤差の限界を予め指定しておくことができる.これは数値分析と分野知識によって決まる.方法は以下の通りです.
浮動小数点表示と実パラメータの指定
using namespace std;

const double epsilon = 1e-16; // 오차의 한계
if (abs(d1 - d2) < epsilon) // 절댓값 처리
	cout << "approximately equal" << endl;
else
	cout << "not equal" << endl;
return (0);
3.6論理演算子論理演算子
short circuit evaluation
if (ture && ++i) // and operator의 계산속도를 위해 && 우변의 ++i는 기능하지 않는다! (좌변이 이미 참인경우 우변을 무시)
// 이렇게 코드를 작성하는것은 지양해야 한다
De Morgan's Law
!(x && y) == !(x || !y)
XOR
flase flase -> flase
flase ture -> ture
true false -> true
true true -> false
C++に論理XOR演算子はありません.ビットXOR演算子があります.
優先度の考慮事項
bool v1 = true;
bool v2 = false;
bool v3 = false;

bool r1 = v1 || v2 && v3; // case1
bool r3 = v1 || (v2 && v3); // case2
&&演算子の優先度は||演算子の優先度より高いため、case 1の機能はcase 2と同じである.この場合、誤解を防ぐために()を適切に打つべきである.
3.8ビット演算子ビット操作
ビット演算子を使用してアレイや構造タイプの演算を行うよりも、メモリの使用がより意味があります.演算子とその機能は次のとおりです.
  • << left shift
  • >> right shift
  • ~ bitwise not
  • & bitwise and
  • | bitwise or
  • ^ bitwise xor
  • #include <iostream>
    #include <bitset>
    
    int main(void)
    {
    	using namespace std;
    	
    	unsigned int a = 3;
    	cout << bitset<8>(a << 1) << " " << (a << 1) << endl;
    	cout << bitset<8>(a << 2) << " " << (a << 2) << endl;
    	cout << bitset<8>(a << 3) << " " << (a << 3) << endl;
    	cout << bitset<8>(a << 4) << " " << (a << 4) << endl;
    	return (0);
    }
    
    // result
    00000110 6
    00001100 12
    00011000 24
    00110000 48
    #include <iostream>
    #include <bitset>
    
    int main(void)
    {
    	unsigned int a = 0b1100;
    	unsigned int b = 0b0110;
    
    	cout << bitset<4>(a & b) << endl;
    	cout << bitset<4>(a | b) << endl;
    	cout << bitset<4>(a ^ b) << endl;
    	return (0);
    }
    
    // result
    0100
    1110
    1010
    
    a &= b; // 비트단위 연산은 assignment operator와 결합하여 사용할 수도 있다
    3.9ビットフラグ、ビットマスク用法ビットフラグ、ビットマスク
    ビットマークやミートソースマスクは、ゲームプログラミングなどの速度の重要な分野で役立ちます.
    ビットマーク
    #include <iostream>
    #include <bitset>
    
    int main(void)
    {
    	const unsigned char opt0 = 1 << 0;
    	const unsigned char opt1 = 1 << 1;
    	const unsigned char opt2 = 1 << 2;
    	const unsigned char opt3 = 1 << 3;
    
    	unsigned char items_flag = 0; // init
    
    	// item0 on
    	items_flag |= opt0;
    	cout << "item3 obtained " << bitset<8>(items_flag) << endl; // 00000001
    
    	// obtain item 2, 3
    	items_flag |= (opt2 | opt3);
    	cout << "item2, 3 obtained" << bitset<8>(opt2 | opt3) << endl;
    
    	// item3 lost
    	itmes_flag &= ~opt3;
    	cout << "item3 obtained " << bitset<8>(items_flag) << endl;
    
    	// has item0?
    	if (items_flag & opt0)
    		cout << "has item0" << endl;
    
    	return (0);
    }
    ビットマスク
    #include <iostream>
    #include <bitset>
    
    using namespace std;
    
    int main(void)
    {
    	const unsigned int red_mask = 0xFF0000;
    	const unsigned int green_mask = 0x00FF00;
    	const unsigned int blue_mask = 0x0000FF;
    
    	cout << bitset<32>(red_mask) << endl;
    	cout << bitset<32>(green_mask) << endl;
    	cout << bitset<32>(blue_mask) << endl;
    
    	unsigned int pixel_color = 0xDAA520;
    	cout << bitset<32>(pixel_color) << endl;
    
    	unsigned char green = pixel_color & green_mask >> 8;
    	cout << "green " << bitset<8>(green) << " " << int(green) << endl;
    	return (0);
    }