Saya ingin menjadi lebih baik tentang mengetahui kapan saya harus berperan. Apa aturan konversi tipe implisit dalam C ++ saat menambahkan, mengalikan, dll. Misalnya,
int + float = ?
int * float = ?
float * int = ?
int / float = ?
float / int = ?
int / int = ?
int ^ float = ?
dan lain-lain ...
Akankah ekspresi selalu dievaluasi sebagai tipe yang lebih tepat? Apakah aturannya berbeda untuk Java? Harap perbaiki saya jika saya telah menjawab pertanyaan ini dengan tidak akurat.
^
adalah XOR.Jawaban:
Dalam operator C ++ (untuk tipe POD) selalu bertindak pada objek dengan tipe yang sama.
Jadi jika mereka tidak sama satu akan dipromosikan untuk mencocokkan yang lain.
Jenis hasil operasi sama dengan operan (setelah konversi).
Catatan. Ukuran minimum operasi adalah
int
. Jadishort
/char
dipromosikan untukint
sebelum operasi dilakukan.Dalam semua ekspresi Anda,
int
dipromosikan kefloat
sebelum operasi dilakukan. Hasil operasi adalah afloat
.sumber
char
. Jika nilaichar + char
ditugaskan kechar
, maka itu hanya dapat melakukan aritmatikachar
dan misalnya membungkus. Tetapi jika hasilnya ditugaskanint
maka harus melakukan aritmatika dalam jenis yang cukup besar untuk mendapatkan hasil yang benar ketika lebih dariCHAR_MAX
.((int) 4) - ((unsigned int) 5)
akan menghasilkan4294967295
int 32 bit dan 32 bit int unsigned.Operasi aritmatika yang melibatkan
float
hasil dalamfloat
.Untuk jawaban lebih detail. Lihatlah apa yang dikatakan bagian §5 / 9 dari Standar C ++
sumber
double
atau tidaklong double
.long long
danunsigned long
tidak dibahas di sini.float
tidak memiliki cukup bit dalam mantissa (24 bit untuk IEEE-754 ) untuk 32-bitint
, jadi mungkin ada beberapa kehilangan data. A 64-bitdouble
seharusnya baik-baik saja.Karena jawaban lain jangan bicara tentang aturan di C ++ 11, inilah salah satunya. Dari standar C ++ 11 (draft n3337) §5 / 9 (menekankan perbedaan):
Lihat di sini untuk daftar yang sering diperbarui.
sumber
Jawaban ini sebagian besar diarahkan pada komentar yang dibuat oleh @ RafałDowgird:
Perlu diingat bahwa standar C ++ memiliki aturan "as-jika" yang sangat penting. Lihat bagian 1.8: Eksekusi Program:
Kompiler tidak dapat menetapkan
int
ukuran 8 bit, bahkan jika itu yang tercepat, karena standar mengamanatkan minimum 16-bitint
.Oleh karena itu, dalam kasus komputer teoretis dengan operasi 8-bit super cepat, promosi implisit ke
int
untuk aritmatika bisa menjadi masalah. Namun, untuk banyak operasi, Anda tidak dapat mengetahui apakah kompiler benar-benar melakukan operasi dalam ketepatanint
dan kemudian dikonversi menjadichar
untuk menyimpan dalam variabel Anda, atau jika operasi dilakukan di char selama ini.Misalnya, pertimbangkan
unsigned char = unsigned char + unsigned char + unsigned char
, di mana penambahan akan meluap (mari kita asumsikan nilai 200 untuk masing-masing). Jika Anda dipromosikan keint
, Anda akan mendapatkan 600, yang kemudian secara implisit akan dilemparkan ke dalamunsigned char
, yang akan membungkus modulo 256, sehingga memberikan hasil akhir dari 88. Jika Anda tidak melakukan promosi seperti itu, Anda harus membungkus antara yang pertama dua tambahan, yang akan mengurangi masalah dari200 + 200 + 200
ke144 + 200
, yaitu 344, yang berkurang menjadi 88. Dengan kata lain, program tidak mengetahui perbedaannya, sehingga kompiler bebas untuk mengabaikan mandat untuk melakukan operasi perantaraint
jika operan memiliki peringkat lebih rendah dariint
.Ini berlaku secara umum penambahan, pengurangan, dan multiplikasi. Itu tidak benar secara umum untuk pembagian atau modulus.
sumber
Jika Anda mengecualikan tipe yang tidak ditandatangani, ada hierarki yang diurutkan: char yang ditandatangani, pendek, int, panjang, panjang, float, ganda, panjang ganda. Pertama, apa pun yang datang sebelum int di atas akan dikonversi menjadi int. Kemudian, dalam operasi biner, tipe peringkat yang lebih rendah akan dikonversi ke yang lebih tinggi, dan hasilnya akan menjadi tipe yang lebih tinggi. (Anda akan mencatat bahwa, dari hierarki, kapan saja titik mengambang dan tipe integral terlibat, tipe integral akan dikonversi ke tipe titik mengambang.)
Unsigned merumitkan hal-hal sedikit: itu mengganggu peringkat, dan bagian-bagian dari peringkat menjadi implementasi yang ditetapkan. Karena itu, yang terbaik adalah tidak mencampur ditandatangani dan tidak ditandatangani dalam ekspresi yang sama. (Kebanyakan ahli C ++ tampaknya menghindari unsigned kecuali jika operasi bitwise terlibat. Itulah, setidaknya, apa yang direkomendasikan Stroustrup.)
sumber
int
untuk nomor yang tidak perlu negatif adalah pemborosan total hingga 50% dari kisaran yang tersedia. Saya tentu saja tidak Stroustrup, tetapi saya menggunakanunsigned
secara default dansigned
hanya ketika saya punya alasan.bool in_order(vector<T> vec) { for ( int i = 0; i < size() - 1; ++i) { if (vec[i + 1] < vec[i]) return false; } return true;
dan kemudian Anda akan merasa terganggu untuk menemukan bahwa itu crash untuk vektor kosong karena ukuran () - 1 mengembalikan 18446744073709551615.Saya solusi untuk masalah mendapat WA (jawaban yang salah), maka saya mengubah salah satu
int
untuklong long int
dan itu memberi AC (menerima) . Sebelumnya, saya coba lakukanlong long int += int * int
, dan setelah saya perbaikilong long int += long long int * int
. Googling saya datang dengan,1. Konversi Aritmatika
Ketentuan untuk Konversi Jenis:
Ketentuan Bertemu ---> Konversi
Salah satu dari operan adalah tipe double panjang . ---> Operand lainnya dikonversi ke tipe double panjang .
Kondisi sebelumnya tidak terpenuhi dan kedua operan bertipe double . ---> Operand lainnya dikonversi menjadi tipe double .
Kondisi sebelumnya tidak terpenuhi dan salah satu operan adalah tipe float . ---> Operand lainnya dikonversi ke tipe float .
Kondisi sebelumnya tidak terpenuhi (tidak ada operan yang tipe mengambang). ---> Promosi integral dilakukan pada operan sebagai berikut:
2. Aturan konversi bilangan bulat
Jenis integer yang lebih kecil dari int dipromosikan ketika operasi dilakukan pada mereka. Jika semua nilai tipe asli dapat direpresentasikan sebagai int, nilai tipe yang lebih kecil dikonversi ke int; jika tidak, itu dikonversi ke int yang tidak ditandatangani. Promosi integer diterapkan sebagai bagian dari konversi aritmatika biasa ke ekspresi argumen tertentu; operan dari operator +, -, dan ~ unary; dan operan dari operator shift.
Peringkat Konversi Integer:
long long int
akan lebih besar dari pangkatlong int
, yang akan lebih besar dari pangkatint
, yang akan lebih besar dari pangkatshort int
, yang akan lebih besar dari pangkatsigned char
.char
harus sama dengan pangkatsigned char
danunsigned char
.Konversi Aritmatika Biasa:
sumber
Bab 4 seluruh berbicara tentang konversi, tetapi saya pikir Anda harus paling tertarik pada ini:
4.5 Promosi integral [conv.prom] Nilai
dari tipe char, char yang ditandatangani, char yang tidak ditandatangani, int yang pendek, atau unsigned yang dapat dikonversi menjadi nilai dari tipe int jika int dapat mewakili semua nilai dari tipe sumber; selain itu
, nilai sumber dapat dikonversi ke nilai jenis int unsigned.
Nilai dari tipe wchar_t (3.9.1) atau tipe enumeration (7.2) dapat dikonversi ke nilai pertama
dari tipe berikut yang dapat mewakili semua nilai dari tipe yang mendasarinya: int, int unsigned int,
long, atau unsigned panjang.
Nilai untuk bidang bit integral (9,6) dapat dikonversi ke nilai jenis int jika int dapat mewakili semua
nilai bidang bit; jika tidak, dapat dikonversi ke int yang tidak ditandatangani jika int yang tidak ditandatangani dapat
kirim ulang semua nilai bit-field. Jika bit-field lebih besar, tidak ada promosi integral yang berlaku. Jika
bidang-bit memiliki tipe yang disebutkan, itu diperlakukan sebagai nilai lain dari tipe itu untuk tujuan promosi.
Nilai dari tipe bool dapat dikonversi menjadi nilai dari tipe int, dengan false menjadi nol dan benar
menjadi satu.
Konversi ini disebut promosi integral.
4,6 Floating point promotion [conv.fpprom] Nilai
dari tipe float dapat dikonversi menjadi nilai tipe double. Nilai tidak berubah.
Konversi ini disebut promosi floating point.
Karenanya, semua konversi yang melibatkan float - hasilnya adalah float.
Hanya yang melibatkan kedua int - hasilnya adalah int: int / int = int
sumber
Jenis ekspresi, ketika tidak kedua bagian dari jenis yang sama, akan dikonversi menjadi yang terbesar dari keduanya. Masalahnya di sini adalah untuk memahami mana yang lebih besar dari yang lain (tidak ada hubungannya dengan ukuran dalam byte).
Dalam ekspresi yang melibatkan bilangan real dan bilangan bulat, bilangan bulat akan dipromosikan ke bilangan real. Misalnya, dalam int + float, tipe ekspresi adalah float.
Perbedaan lainnya terkait dengan kemampuan tipe. Misalnya, ekspresi yang melibatkan int dan int panjang akan menghasilkan tipe long int.
sumber
long
"lebih besar" dari afloat
tetapi apa jenislong
+float
?Peringatan!
Konversi terjadi dari kiri ke kanan.
Coba ini:
sumber
j + i * k
akan menghasilkan 101.