Bár van ilyen operátor – **
a Pythonban, kíváncsi voltam, miért nincs a Java és a C ++ egyet is.
Könnyű létrehozni egyet a C ++ nyelven definiált osztályokhoz az operátor túlterhelésével (és úgy gondolom, hogy ez Java-ban is lehetséges), de amikor olyan primitív típusokról beszélünk, mint az int, double és a így tovább: olyan könyvtárfunkciót kell használnia, mint a Math.power
(és általában mindkettőt duplázni kell).
Tehát – miért ne definiálhatna ilyen operátort primitív típusokhoz?
Megjegyzések
Válasz
Általánosságban elmondható, hogy a primitív operátorok C-ben (és kiterjesztve C ++) úgy vannak megtervezve, hogy egyszerű hardverrel nagyjából egyetlen utasításban megvalósíthatók legyenek. A hatványozáshoz hasonló dolog gyakran szoftveres támogatást igényel; tehát alapértelmezés szerint nincs meg.
Ezenkívül a nyelv szokásos könyvtárából származik std::pow
formájában.
Végül, ha ezt teljes egészű adattípusoknál csinálnánk, akkor nem lenne sok értelme, mert a kis hatványozási értékek többsége elfújja az int-hez szükséges tartományt, azaz 65 535-ig terjedhet. Persze, ezt megteheti párosok és lebegők esetén is, de nem Ints, de miért teszi a nyelvet inkonzisztenssé egy ritkán használt funkcióhoz?
Megjegyzések
- Bár ezzel egyetértek, az a tény, hogy a modulus operátor nem használható lebegőpontos típusokon, ellentmondásos a primitív adattípusoknál, de valószínűleg ez sem egyetlen utasítás lenne egyetlen hardveren sem, amelyről azt gondolom, hogy jelenleg bármilyen módon elterjedt.
- @Sion: Legalábbis x86, a modulus egyetlen utasítás. (
DIV
osztást és modulust is végrehajt) Mindazonáltal ‘ elérte a konzisztencia pontot. - @Billy ONeal: Lebegőpontos modul lus egyetlen utasításban? ‘ Még nem késeltem össze a gyülekezésben, mivel későn tudtam meg magamról. Ha ez ‘ eset, akkor a modulusz operátort lebegőpontos típusokra kell alkalmazhatóvá tenni.
- @DonalFellows: A FORTRAN jóval azelőtt rendelkezett a hatványozási operátorral, bármi, ami hasonlít a bignum támogatásra.
- @DonalFellows: Az energiaszolgáltató nem ‘ t olyan hasznos egész számoknál, mint az úszóknál, de kis teljesítményeknél (főleg négyzeteknél) mindenképpen megvannak a felhasználásai. Személy szerint szeretem azt a megközelítést, hogy operátorokat készítenek betűkből (ahogy Pascal teszi
div
vagy FORTRAN.EQ.
); A nyelvi szóköz szabályaitól függően előfordulhat, hogy tetszőleges számú operátort állítunk elő anélkül, hogy fenntartanánk a szavakat.
Válasz
Ez a kérdés megválaszolható a C ++ esetében: Stroustrup,” A C ++ kialakítása és fejlődése “ezt a 11.6.1. szakaszban tárgyalja, 247–250. oldal.
Általános kifogások merültek fel a új üzemeltető. Ez kiegészítené a már túlbonyolított elsőbbségi táblázatot. A munkacsoport tagjai úgy gondolták, hogy ez csak kisebb kényelmet jelent a funkcióval szemben, és szerették volna, ha néha helyettesíteni tudják saját funkcióikat.
Nem volt jó jelölt üzemeltetőnek.A ^
kizárólagos vagy, és ^^
zavart keltett a &
és a |
és &&
és ||
. A !
alkalmatlan volt, mivel természetes hajlam lenne !=
-et írni egy létező érték hatványozására, és ez már megtörtént. A legjobb elérhető lehet a *^
, ami nyilvánvalóan senkinek sem tetszett.
A Stroustrup ismét úgy gondolta, hogy **
, de már van jelentése a C-ben: char ** c;
a c
-t deklarálja a char
mutatóra mutató mutatóként. Az **
bevezetése tokenként, amely jelentése: “mutató a mutatóra mutató mutató”, “a következő dolog mire mutat” (ha “sa mutatót mutat”) vagy “hatványozás” (ha követi) számmal) prioritási problémákat okozott. a/b**p
-nek a/(b**p)
-ként kell elemeznie, ha p szám lenne, de “>
ha p lenne mutató, ezért ezt az elemzőben kellene megoldani.
Más szavakkal, lehetséges lett volna, de ez bonyolította volna az elsőbbségi táblázatot és a értelmező, és mindkettő már túl bonyolult.
Nem ismerem a Java történetét; csak spekulálni tudtam. Ami a C-t illeti, ahol kezdődött, az összes C operátor könnyen lefordítható összeállítási kódba, részben a fordító egyszerűsítése, részben pedig az egyszerű operátorok időigényes funkcionalitásának elrejtése érdekében (az a tény, hogy operator+()
és mások el tudták rejteni a bonyolultságot, és a teljesítmény slágerei a C ++ egyik korai panasza voltak.
Megjegyzések
- Kedves válasz. Gondolom, a Java megpróbálta egyszerűsíteni a C-t ebben a tekintetben, így senki sem akart új operátort felvenni. Ez ‘ kár, amit senki sem kérdezett tőlem, biztosan szerettem volna
*^
. : D - A szövegformázás elvégzésére a C-t építették. A Fortran matematika készítésére épült, és 20 évvel korábban bonyolult, erő és mátrix matematikával rendelkezett.
- @Martin Beckett: Találna bizonyítékot arra, hogy a C szöveget formázta? Számomra nagyon esetlen nyelvnek tűnik ehhez, és amit ‘ olvastam a C eredetéről, azt állítja, hogy elsősorban a Unix rendszerprogramozására tervezték.
- @DavidThornley – Úgy tervezték, hogy Unixot írjon bele, de úgy tűnik, hogy a korai Unix összes használata szövegformázás volt, ezért ‘ időre kiterjedt karakterlánccal és i / o könyvtár.
- +1: A
a**p
jelentése a gyilkos. (A feltörések a probléma kiküszöbölésére … Brr!)
Válasz
gyanítom ez azért van, mert minden általad bevezetett operátor növeli a nyelv bonyolultságát. A belépés gátja ezért nagyon magas. Nagyon, nagyon ritkán használom a hatványozást – és nagyon örülök, ha metódust hívok így.
Megjegyzések
- Minden szolgáltatás -100 ponttal indul.
- Én ‘ d
x**2
ésx**3
nem olyan ritkán használom . És jó lenne egy varázslat, amelyet a fordító tud és optimalizál az egyszerű esetekre. - @CodeInChaos:
x * x
ésx * x * x
aren ‘ t nem helyettesítheti a négyzetet és a kockát. - @David ‘ t egyszerűen írja be:
x*x
, ha x kifejezés. A legjobb esetben a kód nehézkessé válik, a legrosszabb esetben pedig lassabban vagy akár rosszul is. Tehát ‘ meg kell határoznia a saját Négyzet és Kocka funkcióit. És még akkor is csúnyább lenne a kód, mint a ** szolgáltatót használni. - @David Igen, zárójeleket kell tennem, de ne ‘ nem kell megismételni a kifejezés többször és felduzzasztja a forráskódot. Ami nagyon csökkenti az olvashatóságot. A gyakori szubkifejezések kiküszöbölése csak akkor lehetséges, ha a fordító garantálni tudja, hogy a kifejezés mellékhatásoktól mentes legyen. És legalább .net jitter nem ‘ ebben a tekintetben túl okos.
Válasz
A Java nyelv és az alapkönyvtár tervezői úgy döntöttek, hogy a legtöbb matematikai műveletet a Math osztályba helyezik át. Lásd: Math.pow () .
Miért? Rugalmasság a teljesítmény fontossági sorrendbe állításához a bitről bitre pontossággal szembenA többi nyelvspecifikációval ellentétes lenne azt állítani, hogy a beépített matematikai operátorok viselkedése platformonként változhat, míg a Math osztály kifejezetten kijelenti, hogy a viselkedés potenciálisan feláldozza a teljesítmény pontosságát, ezért a vevő óvakodjon:
Ellentétben a StrictMath osztály egyes numerikus módszereivel, az osztály egyenértékű függvényeinek összes megvalósítása A matematika nincs megadva, hogy a bitről bitre ugyanazokat az eredményeket adja vissza. Ez a relaxáció lehetővé teszi a jobban teljesítő megvalósításokat, ahol nincs szükség szigorú reprodukálhatóságra.
Válasz
A hatványozás kezdettől fogva része volt a Fortran-nak, mert egyenesen a tudományos programozásra irányult. A mérnökök és fizikusok gyakran használják a szimulációkban, mert a fizikában gyakoriak az erőtörvényi viszonyok.
A Python a tudományos számítástechnikában is erőteljesen jelen van (pl. NumPy és SciPy). Ez a hatványozási operátorával együtt azt sugallja, hogy a tudományos programozást is megcélozta.
A C, a Java és a C # a rendszer programozásában gyökerezik. Talán ez olyan hatás, amely távol tartotta a hatványozást a támogatott operátorok csoportjától.
Csak elmélet.
Válasz
A C operátorokat csak az ALU-val elérhető közös számtani műveletekhez definiálta. Fő célja egy ember által olvasható interfész létrehozása az Assembly kódhoz.
A C ++ nem változtatott semmilyen operátor viselkedésen, mert mindent szeretett volna a C-ben írt kódbázis megfelelõ.
A Java ugyanezt tette, mert nem akarta megfélemlíteni a meglévõ C ++ programozókat.
Megjegyzések
- A C létrehozásakor a szorzás és osztás nem ritkán hiányzott a hardverből, és szoftverben kellett végrehajtani. A C-nek azonban vannak szorzási és osztási operátorai.
- @siride: Tudomásom szerint a PDP-7, amely az első Unix futtató számítógép, hardveres szorzást és osztást végzett EAE-jén keresztül. Kérjük, olvassa el: bitsavers.org/pdf/dec/pdp7/F-75_PDP-7userHbk_Jun65.pdf
Válasz
Nos, mert minden olyan operátor már használatban van, amelyiknek lenne értelme egy áramellátáshoz. ^ XOR és ** egy mutatót definiál. Tehát ehelyett csak egy funkciójuk van, amely ugyanazt csinálja. (mint a pow ())
Megjegyzések
- @RTS – Egy langauge fejlesztő valóban több értelmet keres, mint hatékonyság?
- A programozási nyelv jó fejlesztője mindkettőt megnézi. ‘ nem mondhatok semmit a java-ról. De a c ++ – ban a pow () függvényt a fordítás idején számítják ki. És ugyanolyan hatékony, mint a szokásos operátorok.
- @RTS: A
pow()
függvény futás közben végzi a számítását, hacsak nincs fordítója, amely képes állandó hajtogatásra apow()
számára, amiben nagyon kétlem. (Néhány fordító lehetőséget ad arra, hogy a számítás elvégzéséhez belső processzorokat használjon.) - @In silico nem azt értettem, hogy ‘ értéket, arra gondoltam, hogy a fordítók optimalizálják a függvényhívást, tehát csak a nyers egyenlet áll rendelkezésedre.
- @josefx: Bizonyára ‘ ez jó ok. Az egyetlen
*
egy lexikális token, függetlenül attól, hogy ‘ -et használnak-e iránymutatáshoz vagy szorzáshoz. A**
jelentése, hogy a hatványozás egy vagy két lexikális tokent jelentene, és nem igazán akarja, hogy vdxer-nek el kell találnia a szimbólumot a tokenizálandó táblázat.
Válasz
Tény, hogy az aritmetikai operátorok csak a funkciók parancsikonjai. (Majdnem) Minden, amit velük tesz, egy funkcióval elvégezhető. Példa:
c = a + b; // equals c.set(a.add(b)); // or as free functions set(c, add(a,b));
Ez csak bőbeszédűbb, ezért nem látok semmi rosszat abban, ha függvényeket használunk a “teljesítmény” végrehajtására.
Válasz
Az összeadás / kivonás / tagadás és a szorzás / osztás alapvető matematikai operátor. Ha az operátort hajtaná energiává, hol állna meg? Négyzetgyök operátor? N-root operátor? Logaritmus operátor?
Nem tudok beszélni az alkotóik helyett, de azt mondhatom, hogy szerintem nem lesz nehézkes és nem ortogonális, ha ilyen operátorok vannak a nyelven. A billentyűzeten maradt nem alfa-numerikus / fehér szóköz karakterek száma meglehetősen korlátozott. Valójában furcsa, hogy a C ++ modulus operátora van.
Megjegyzések
- +1 – Nem tudom, ‘ miért nem tudom, miért furcsa, ha operátorként
mod
van. Ez ‘ s általában egyetlen utasítás. Ez ‘ egész számokra vonatkozó primatív műveletet végez. Ez ‘ s mindenütt a számítógép-tudományban használják a legtöbbet.(Olyan dolgok megvalósítása, mint a korlátozott pufferekmod
nélkül, büdösek lennének) - @Billy ONeal: Furcsa, mert nincs következetesség az egész típusú és lebegőpontos típusok között . Abszolút hasznos, és nem álmodnék annak eltávolításáról. Csak furcsa minden.
^
operátor elsőbbsége nem egyezik meg a hatványozás elsőbbségével. Vegyük fontolóra aa + b ^ c
kifejezést. A matematikában először a hatványozást hajtják végre (b ^ c
), majd a kapott erőt hozzáadják aa
-hez. A C ++ nyelven először az összeadást hajtják végre (a + b
), majd a^
operátort ac
. Tehát akkor is, ha a^
operátort a hatványozás jelentette, az elsőbbség mindenkit meglep.^
egy XOR a C ++ értékben. Javasoljuk, hogy a túlterhelt operátor ne tegye különbként azt, amit egy primitív adattípus használ.++
operátort vagy a!
operátort. al. hatványozást jelent. De ‘ t úgyis nem tehet, mert az operátorok, akikről beszél, csak egy argumentumot fogad el; a hatványozáshoz két argumentum szükséges.