Apakah ada hal seperti itu? Ini adalah pertama kalinya saya menemui kebutuhan praktis untuk itu, tetapi saya tidak melihat satu pun yang terdaftar di Stroustrup . Saya bermaksud menulis:
// Detect when exactly one of A,B is equal to five.
return (A==5) ^^ (B==5);
Tetapi tidak ada ^^
operator. Bisakah saya menggunakan bitwise di ^
sini dan mendapatkan jawaban yang benar (terlepas dari representasi mesin yang benar dan salah)? Saya tidak pernah bergaul &
dan &&
, atau |
dan ||
, jadi saya ragu untuk melakukannya dengan ^
dan ^^
.
Saya akan lebih nyaman menulis bool XOR(bool,bool)
fungsi saya sendiri .
Jawaban:
The
!=
Operator melayani tujuan ini untukbool
nilai-nilai.sumber
bool
nilai" karena tidak selalu melakukan apa yang Anda inginkan untuk non-boolean. Dan karena ini adalah C ++, adabool
tipe nyata daripada harus digunakanint
untuk tujuan itu.a
tulis saja!(a) != !(a)
Untuk operasi XOR logis sejati, ini akan bekerja:
Perhatikan
!
apakah ada untuk mengkonversi nilai menjadi boolean dan meniadakannya, sehingga dua bilangan bulat positif yang tidak sama (masing-masing atrue
) akan dievaluasifalse
.sumber
!!
akan bekerja hanya bertanya dengan baik, tetapi karena mereka harus berbeda, meniadakan mereka tidak ada salahnya.Implementasi XOR logis manual yang tepat tergantung pada seberapa dekat Anda ingin meniru perilaku umum operator logis lainnya (
||
dan&&
) dengan XOR Anda. Ada dua hal penting tentang operator ini: 1) mereka menjamin evaluasi hubung singkat, 2) mereka memperkenalkan titik urutan, 3) mereka mengevaluasi operan mereka hanya sekali.Evaluasi XOR, seperti yang Anda mengerti, tidak dapat dihubung pendek karena hasilnya selalu tergantung pada kedua operan. Jadi saya tidak mungkin. Tapi bagaimana dengan 2? Jika Anda tidak peduli dengan 2, maka dengan
bool
operator nilai yang dinormalisasi (yaitu )!=
melakukan pekerjaan XOR dalam hal hasil. Dan operan dapat dengan mudah dinormalisasi dengan unary!
, jika perlu. Dengan demikian!A != !B
mengimplementasikan XOR yang tepat dalam hal itu.Tetapi jika Anda peduli dengan titik sekuens tambahan, baik
!=
bitwise atau tidak^
adalah cara yang tepat untuk menerapkan XOR. Salah satu cara yang mungkin untuk melakukan XOR (a, b) dengan benar mungkin terlihat sebagai berikutIni sebenarnya sedekat yang Anda bisa untuk membuat XOR buatan sendiri "mirip" dengan
||
dan&&
. Ini hanya akan berfungsi, tentu saja, jika Anda menerapkan XOR Anda sebagai makro. Fungsi tidak akan berfungsi, karena pengurutan tidak akan berlaku untuk argumen fungsi.Seseorang mungkin mengatakan, bahwa satu-satunya alasan memiliki titik urutan pada masing
&&
- masing dan||
untuk mendukung evaluasi hubung singkat, dan dengan demikian XOR tidak memerlukannya. Ini masuk akal, sebenarnya. Namun, ada baiknya mempertimbangkan memiliki XOR dengan titik urutan di tengah. Misalnya, ungkapan berikuttelah mendefinisikan perilaku dan hasil khusus dalam C / C ++ (berkaitan dengan sekuensing setidaknya). Jadi, orang mungkin mengharapkan hal yang sama dari XOR logis yang ditentukan pengguna , seperti pada
sementara
!=
XOR yang berbasis tidak memiliki properti ini.sumber
||
dan&&
: C) mereka mengevaluasi operan dalam konteks boolean. Artinya,1 && 2
benar, tidak seperti1 & 2
yang nol. Demikian juga,^^
operator dapat berguna untuk menyediakan fitur tambahan ini, untuk mengevaluasi operan dalam konteks boolean. Misalnya1 ^^ 2
salah (tidak seperti1 ^ 2
).#define XOR(ll,rr) { ll ? !rr : rr }
, maka panggilan sepertiint x = 2; XOR(++x > 1, x < 5);
akan memberikan hasil yang salah. Panggilan itu harus memiliki tanda kurung tambahan, seperti diint x = 2; XOR( (++x > 1), (x < 5) );
, untuk memberikan hasil yang diharapkan benar.Ada cara lain untuk melakukan XOR:
Yang jelas dapat ditunjukkan bekerja melalui:
sumber
Operator XOR tidak dapat dihubung pendek; yaitu Anda tidak dapat memprediksi hasil ekspresi XOR hanya dengan mengevaluasi operan tangan kirinya. Jadi, tidak ada alasan untuk menyediakan
^^
versi.sumber
&&
dan&
sama sekali. Maksudnya adalah tidak ada alasan untuk memperkenalkan^^
. Properti yang^^
akan menganggap nilai bukan nol sebagai1
tidak benar-benar berguna, saya curiga. Atau setidaknya saya tidak bisa melihat kegunaannya.Ada beberapa kode yang diposting yang memecahkan masalah lebih baik daripada! A! =! B
Perhatikan bahwa saya harus menambahkan BOOL_DETAIL_OPEN / CLOSE agar ini akan berfungsi pada MSVC 2010
sumber
Gunakan yang sederhana:
sumber
Berikut adalah bagaimana saya pikir Anda menulis perbandingan XOR di C ++:
Bukti
Buktinya adalah bahwa studi lengkap input dan output menunjukkan bahwa dalam dua tabel, untuk setiap set input hasilnya selalu sama dalam dua tabel.
Karena itu, pertanyaan awal adalah bagaimana cara menulis:
Jawabannya adalah
Atau jika Anda suka, tulis
sumber
(A || B) && !(A && B)
Bagian pertama adalah A OR B, yang merupakan OR Inklusif; bagian kedua adalah, BUKAN A DAN B. Bersama-sama Anda mendapatkan A atau B, tetapi tidak A dan B.
Ini akan memberikan XOR terbukti dalam tabel kebenaran di bawah ini.
sumber
Saya menggunakan "xor" (sepertinya itu adalah kata kunci; dalam Kode :: Blok setidaknya menjadi berani) sama seperti Anda dapat menggunakan "dan" bukannya
&&
dan "atau" bukannya||
.Ya, itu bitwise. Maaf.
sumber
and
danxor
merupakan macro library standar. Mereka bukan dari "suatu tempat", mereka berasal dari <iso646.h>. Makro ini juga ada di C99 (tidak yakin tentang C89 / 90).xor
singkatan dari bitwise xor though, sementaraand
masih logis dan.struct A { compl A() { } };
untuk mendefinisikan destruktor, misalnya.Ini berfungsi seperti yang didefinisikan. Persyaratannya adalah untuk mendeteksi jika Anda menggunakan Objective-C , yang meminta BOOL alih-alih bool (panjangnya berbeda!)
sumber