Meskipun ada operator seperti itu - **
dengan Python, saya bertanya-tanya mengapa Java dan C ++ tidak memilikinya juga.
Sangat mudah untuk membuat satu untuk kelas yang Anda definisikan di C ++ dengan operator overloading (dan saya percaya hal seperti itu mungkin juga di Jawa), tetapi ketika berbicara tentang tipe primitif seperti int, double dan sebagainya, Anda harus menggunakan perpustakaan berfungsi seperti Math.power
(dan biasanya harus melakukan keduanya untuk menggandakan).
Jadi - mengapa tidak mendefinisikan operator semacam itu untuk tipe primitif?
^
operator tidak sesuai dengan prioritas eksponen. Pertimbangkan ungkapannyaa + b ^ c
. Dalam matematika, eksponensial dilakukan pertama kali (b ^ c
), kemudian kekuatan yang dihasilkan ditambahkana
. Dalam C ++, penambahan dilakukan terlebih dahulu (a + b
) kemudian^
operator dilakukan denganc
. Jadi, bahkan jika Anda benar-benar mengimplementasikan^
operator berarti eksponensial, prioritasnya akan mengejutkan semua orang.^
adalah XOR dalam C ++. Disarankan agar operator yang kelebihan beban tidak melakukan apa pun yang dilakukan oleh tipe data primitif.++
operator atau!
operator et. Al. berarti eksponen. Tetapi Anda tidak dapat melakukannya, karena operator yang Anda bicarakan hanya menerima satu argumen; eksponensial membutuhkan dua argumen.Jawaban:
Secara umum, operator primitif dalam C (dan dengan ekstensi C ++) dirancang untuk dapat diterapkan oleh perangkat keras sederhana dalam kira-kira satu instruksi tunggal. Sesuatu seperti eksponensial sering kali memerlukan dukungan perangkat lunak; jadi tidak ada di sana secara default.
Juga, disediakan oleh perpustakaan standar bahasa dalam bentuk
std::pow
.Akhirnya, melakukan ini untuk tipe data integer tidak akan masuk akal, karena sebagian besar nilai eksponensial bahkan kecil mengeluarkan kisaran yang diperlukan untuk int, yaitu hingga 65.535. Tentu, Anda bisa melakukan ini untuk ganda dan mengapung tetapi tidak int, tetapi mengapa membuat bahasa tidak konsisten untuk fitur yang jarang digunakan?
sumber
DIV
Apakah divisi dan modulus) Anda punya saya pada titik konsistensi.div
atau FORTRAN dengan.EQ.
); tergantung pada aturan spasi putih bahasa, dimungkinkan untuk memiliki jumlah operator yang sewenang-wenang tanpa mengharuskan mereka untuk memesan kata-kata.Pertanyaan ini dapat dijawab untuk C ++: Stroustrup, "Desain dan Evolusi C ++" membahas hal ini di bagian 11.6.1, hlm. 247-250.
Ada keberatan umum untuk menambah operator baru. Itu akan menambah tabel prioritas yang sudah terlalu rumit. Para anggota kelompok kerja berpikir bahwa itu hanya akan memberikan sedikit kenyamanan daripada memiliki fungsi, dan mereka ingin dapat mengganti fungsi mereka sendiri kadang-kadang.
Tidak ada kandidat yang baik untuk operator.
^
eksklusif-atau, dan^^
kebingungan diundang karena hubungan antara&
dan|
dan&&
dan||
.!
tidak cocok karena akan ada kecenderungan alami untuk menulis!=
untuk nilai yang sudah ada, dan itu sudah diambil. Yang terbaik mungkin tersedia*^
, yang tampaknya tidak ada yang benar-benar suka.Stroustrup dipertimbangkan
**
lagi, tetapi sudah memiliki arti dalam C:a**p
adalaha
kali apa punp
menunjuk ke, danchar ** c;
menyatakanc
sebagai pointer ke pointer kechar
. Memperkenalkan**
sebagai token yang berarti "deklarasi pointer ke pointer ke", "berapa kali hal berikutnya menunjuk ke" (jika itu adalah pointer) atau "eksponensial" (jika diikuti oleh angka) menyebabkan masalah diutamakan.a/b**p
harus mengurai seolah-a/(b**p)
olah p adalah angka, tetapi(a/b) * *p
jika p adalah pointer, jadi ini harus diselesaikan di parser.Dengan kata lain, itu mungkin saja terjadi, tetapi itu akan memperumit tabel presedensi dan pengurai, dan keduanya sudah terlalu rumit.
Saya tidak tahu cerita tentang Jawa; yang bisa saya lakukan hanyalah berspekulasi. Adapun C, di mana itu dimulai, semua operator C mudah diterjemahkan ke dalam kode assembly, sebagian untuk menyederhanakan kompiler dan sebagian untuk menghindari menyembunyikan fungsi yang memakan waktu dalam operator sederhana (fakta bahwa
operator+()
dan yang lain dapat menyembunyikan kerumitan besar dan hit kinerja adalah satu dari keluhan awal tentang C ++).sumber
*^
. : Da**p
adalah si pembunuh. (Peretasan untuk mengatasi masalah itu ... Brr!)Saya menduga itu karena setiap operator yang Anda perkenalkan meningkatkan kompleksitas bahasa. Karena itu penghalang untuk masuk sangat tinggi. Saya menemukan diri saya menggunakan exponentiation sangat, sangat jarang - dan saya lebih dari senang untuk menggunakan pemanggilan metode untuk melakukannya.
sumber
x**2
danx**3
tidak jarang. Dan implementasi pow ajaib yang diketahui oleh kompiler dan dioptimalkan untuk kasus-kasus sederhana akan lebih baik.x * x
danx * x * x
bukan pengganti yang buruk untuk kuadrat dan kubus.x*x
jika x adalah ekspresi. Dalam kasus terbaik, kode menjadi sulit digunakan, dan dalam kondisi terburuk lebih lambat atau bahkan salah. Jadi, Anda perlu mendefinisikan fungsi Square dan Cube Anda sendiri. Dan bahkan kodenya akan lebih jelek daripada menggunakan ** sebagai operator listrik.Perancang perpustakaan inti dan bahasa Jawa memutuskan untuk menurunkan sebagian besar operasi matematika ke kelas Matematika . Lihat Math.pow () .
Mengapa? Fleksibilitas untuk memprioritaskan kinerja di atas presisi bit-for-bit. Akan bertentangan dengan spesifikasi bahasa lainnya untuk mengatakan bahwa perilaku operator matematika bawaan dapat bervariasi dari platform ke platform, sedangkan kelas Matematika secara khusus menyatakan bahwa perilaku tersebut berpotensi mengorbankan presisi untuk kinerja, sehingga pembeli berhati-hati:
sumber
Eksponen adalah bagian dari Fortran sejak awal karena ditujukan tepat pada pemrograman ilmiah. Insinyur dan fisikawan sering menggunakannya dalam simulasi, karena hubungan kekuatan hukum umum dalam fisika.
Python memiliki kehadiran yang kuat dalam komputasi ilmiah, juga (misalnya NumPy dan SciPy). Itu, bersama dengan operator eksponensial, menyarankan bahwa itu ditujukan untuk pemrograman ilmiah juga.
C, Java, dan C # memiliki akar dalam pemrograman sistem. Mungkin itu pengaruh yang membuat eksponensial keluar dari kelompok operator yang didukung.
Hanya sebuah teori.
sumber
C hanya operator yang ditentukan untuk operasi aritmatika umum yang dapat diakses dengan ALU. Tujuan utamanya adalah menciptakan antarmuka yang dapat dibaca manusia untuk kode Majelis.
C ++ tidak mengubah perilaku operator karena, ia ingin semua basis kode yang ditulis dalam C sesuai.
Java melakukan hal yang sama karena tidak ingin mengintimidasi programmer C ++ yang ada.
sumber
Yah karena setiap operator yang masuk akal untuk daya sudah digunakan. ^ adalah XOR dan ** mendefinisikan pointer ke pointer. Jadi alih-alih mereka hanya memiliki fungsi yang melakukan hal yang sama. (seperti pow ())
sumber
pow()
Fungsi melakukan komputasi pada saat runtime, kecuali jika Anda punya kompiler yang dapat melakukan pelipatan konstanpow()
, yang saya sangat ragu. (Beberapa kompiler memberi Anda pilihan untuk menggunakan intrinsik prosesor untuk melakukan perhitungan.)*
adalah token leksikal, apakah itu digunakan untuk tipuan atau perkalian. Sebuah**
eksponensial makna akan baik satu atau dua token leksikal, dan Anda benar-benar tidak ingin lexer Anda harus memukul tabel simbol untuk tokenize.Faktanya adalah, operator aritmatika hanyalah pintasan fungsi. (Hampir) Segala sesuatu yang Anda lakukan dengan mereka dapat dilakukan dengan suatu fungsi. Contoh:
Itu hanya lebih verbose, jadi saya melihat tidak ada yang salah dengan menggunakan fungsi untuk melakukan 'kekuatan'.
sumber
Penambahan / pengurangan / negasi dan perkalian / pembagian adalah operator matematika dasar. Jika Anda menjadikan daya sebagai operator, di mana Anda akan berhenti? Operator akar kuadrat? Operator N-root? Operator logaritma?
Saya tidak dapat berbicara untuk pencipta mereka, tetapi saya dapat mengatakan bahwa saya pikir itu akan menjadi sulit dan tidak ortogonal untuk memiliki operator seperti itu dalam bahasa tersebut. Jumlah karakter non-alfanumerik / spasi putih yang tersisa pada keyboard agak terbatas. Seperti itu, aneh bahwa ada operator modulus di C ++.
sumber
mod
sebagai operator itu aneh. Biasanya satu instruksi. Ini adalah operasi primitif pada bilangan bulat. Ini digunakan sebagian besar di mana-mana dalam ilmu komputer. (Menerapkan hal-hal seperti buffer yang dibatasi tanpamod
bau)