Miksi Java / C ++ -sovelluksessa ei ole virtalähdettä?

Vaikka Pythonissa on sellainen operaattori – **, mietin, miksi Java ja C ++ eivät ole yksi.

On helppo tehdä sellainen luokille, jotka määrität C ++: ssa, operaattorin ylikuormituksella (ja uskon, että sellainen on mahdollista myös Java: ssa), mutta kun puhutaan primitiivisistä tyypeistä, kuten int, double ja niin, sinun on käytettävä kirjastotoimintoa, kuten Math.power (ja sinun on yleensä heitettävä molemmat kaksinkertaisiksi).

Joten – miksi et määritä tällaista operaattoria primitiivisille tyypeille?

Kommentit

  • C ++ – järjestelmässä emme voi luoda omia operaattoreitamme. Voit vain ylikuormittaa olemassa olevia operaattoreita.
  • @Mahesh, joten voin luoda oman numeroluokan ja ylikuormittaa ^ -operaattoria voimaksi. Se ei todellakaan ole mather.
  • @RanZilber: Sillä on merkitystä, koska ^ -operaattorin etusija ei vastaa eksponentin prioriteettia. Harkitse lauseketta a + b ^ c. Matematiikassa eksponentio suoritetaan ensin (b ^ c), sitten saatu voima lisätään osioon a. C ++: ssa summaus suoritetaan ensin (a + b), sitten operaattori ^ suoritetaan c. Joten vaikka toteuttaisitkin ^ -operaattorin tarkoittamaan eksponenssia, etusija yllättää kaikki.
  • @RamZilber – ^ on XOR C ++: ssa. On suositeltavaa, että ylikuormitettu operaattori ei tee mitään erilaista kuin primitiivinen tietotyyppi käyttää sitä.
  • @RanZilber: Koska se ’ ei ole lainkaan intuitiivinen käyttää mikä tahansa mainitsemistasi operaattoreista tarkoittaa eksponentointia. Epäilen vakavasti minkä tahansa C ++ -ohjelmoijan pätevyyttä, joka ylikuormittaa ++ -operaattoria tai operaattoria !. al. tarkoittaa eksponentointia. Mutta voit ’ t joka tapauksessa, koska operaattorit, joista puhut, hyväksyvät vain yhden argumentin; eksponentti vaatii kaksi argumenttia.

Vastaus

Yleisesti ottaen C: n primitiiviset operaattorit (ja laajennuksella C ++) on suunniteltu toteutettavaksi yksinkertaisella laitteistolla suunnilleen yhdellä käskyllä. Jotain eksponention kaltainen vaatii usein ohjelmistotukea; joten sitä ei ole oletusarvoisesti.

Lisäksi sen tarjoaa kielen vakiokirjasto muodossa std::pow.

Lopuksi, tekemällä tämä kokonaislukutietotyypeille, ei olisi mitään järkeä, koska useimmat pienetkin eksponentointiarvot puhaltavat int: lle vaaditun alueen, joka on enintään 65 535. Toki, voit tehdä tämän tupla- ja kellukkeille, mutta ei Intia, mutta miksi kielestä tulee epäjohdonmukainen harvoin käytetylle ominaisuudelle?

Kommentit

  • Vaikka olen samaa mieltä suurimmasta osasta, tosiasia, että moduuli operaattoria ei voida käyttää liukulukutyypeissä, on ristiriidassa primitiivisten tietotyyppien kanssa, mutta se ei myöskään todennäköisesti olisi yksittäinen käsky missään laitteistossa, jonka uskon olevan tällä hetkellä yleinen.
  • @Sion: Ainakin x86, moduuli on yksi käsky. (DIV tekee sekä jakamisen että moduulin) Sinä ’ olet kuitenkin saanut minut johdonmukaisuuspisteeseen.
  • @Billy ONeal: Kelluva moduuli lus yhdessä ohjeessa? En ole ’ ollut mutkannut kokoonpanossa myöhään tietääkseni itsestäni. Jos tämä on ’ tapaus, moduulioperaattori tulisi soveltaa liukulukuihin.
  • @DonalFellows: FORTRANilla oli eksponenttioperaattori kauan ennen kuin se oli kaikki, joka muistuttaa bignumin tukea.
  • @DonalFellows: Virtaoperaattori ei ole ’ t yhtä hyödyllinen kokonaislukujen kuin kelluvien kanssa, mutta pienille voimille (etenkin neliöittäminen) se voisi ehdottomasti on sen käyttötarkoitukset. Henkilökohtaisesti pidän lähestymistavasta, jossa operaattorit tehdään kirjaimista (kuten Pascal tekee div tai FORTRAN kanssa .EQ.); kielen välilyöntisäännöistä riippuen voi olla mahdollista, että operaattoreita on mielivaltaisesti tarvitsematta varata sanoja.

Vastaa

Tähän kysymykseen voidaan vastata C ++: Stroustrup,” C ++: n suunnittelu ja kehitys ”käsittelee tätä osiossa 11.6.1, s. 247-250.

A-ryhmän lisäämiseen oli yleisiä vastalauseita. uusi operaattori. Se lisäisi jo liian monimutkaista etusijataulukkoa. Työryhmän jäsenet ajattelivat, että se antaisi vain pienen mukavuuden toiminnon käyttämisessä, ja he halusivat pystyä joskus korvaamaan omat toimintonsa.

Ei ollut hyvää ehdokasta operaattoriksi.^ on yksinomainen tai, ja ^^ kutsui sekaannusta & ja | ja && ja ||. ! oli sopimaton, koska olisi luonnollinen taipumus kirjoittaa != olemassa olevan arvon eksponenttiin, ja se oli jo otettu. Paras käytettävissä oleva tuote on voinut olla *^, josta kukaan ei ilmeisesti pitänyt.

Stroustrup harkitsi uudelleen **, mutta se on jo merkitys C: ssä: a**p on a kertaa mikä tahansa p osoittaa, ja char ** c; julistaa c osoittimeksi, joka osoittaa osoitteen char. Esittelyssä ** tunnuksena, joka tarkoittaa ”osoittimen osoittavan osoittimen osoittamista”, ”kertaa mitä seuraava asia osoittaa” (jos se on ”osoitin”) tai ”eksponentointia” (jos noudatetaan) numerolla) aiheutti etusijaongelmia. a/b**p olisi jäsennettävä muodossa a/(b**p), jos p olisi luku, mutta (a/b) * *p jos p olisi osoitin, niin tämä olisi ratkaistava jäsentimessä.

Toisin sanoen se olisi ollut mahdollista, mutta se olisi monimutkaistanut prioriteettitaulukkoa ja jäsennin, ja molemmat ovat jo liian monimutkaisia.

En tiedä Java-tarinaa; voisin vain spekuloida. C: n kohdalla, josta se alkoi, kaikki C-operaattorit voidaan helposti kääntää kokoonpanokoodiksi, osittain kääntäjän yksinkertaistamiseksi ja osittain välttämään pieleen vievän toiminnallisuuden piilottamista yksinkertaisissa operaattoreissa (tosiasia, että operator+() ja muut voivat piilottaa erittäin monimutkaisen ja suorituskykyhitit olivat yksi varhaisista valituksista C ++: sta).

Kommentit

  • Hieno vastaus. Kai Java yritti yksinkertaistaa C: tä tässä suhteessa, joten kukaan ei halunnut lisätä uutta operaattoria. Että ’ on sääli, jota kukaan ei kysynyt minulta, olisin varmasti halunnut *^. : D
  • C rakennettiin tekstin muotoilua varten. Fortran rakennettiin tekemään matematiikkaa ja sillä oli monimutkainen, teho- ja matriisimatematiikka 20 vuotta aiemmin.
  • @Martin Beckett: Löydätkö todisteita siitä, että C on rakennettu tekstin muotoilua varten? Minusta se tuntuu hyvin kömpelöltä kieleltä, ja se, mitä olen lukenut C: n alkuperästä, sanoo, että se on suunniteltu ensisijaisesti Unixin järjestelmäohjelmointiin.
  • @DavidThornley – Se on suunniteltu kirjoittamaan Unix, mutta kaikki Unixin varhaiset käyttötavat näyttävät olleen tekstin muotoiluja, ja sille ’ on sillä aikaa laaja merkkijono ja i / o kirjasto.
  • +1: a**p: n nykyinen merkitys on tappaja. (Hakkerit ongelman kiertämiseen … Brr!)

Vastaa

Epäilen se ”koska jokainen käyttämäsi operaattori lisää kielen monimutkaisuutta. Siksi pääsy on erittäin korkea este. Käytän eksponentointia hyvin, hyvin harvoin – ja käytän enemmän kuin mielelläni metodikutsua niin.

Kommentit

  • Jokainen ominaisuus alkaa -100 pisteellä.
  • I ’ d käytän x**2 ja x**3 ei niin harvoin . Ja maaginen toteutus, josta kääntäjä tietää ja optimoi yksinkertaiset tapaukset, olisi mukava.
  • @CodeInChaos: Kuitenkin x * x ja x * x * x are ’ t ei korvaa neliötä ja kuutiota.
  • @David voit ’ t yksinkertaisesti kirjoita x*x, jos x on lauseke. Parhaassa tapauksessa koodi muuttuu hankalaksi ja pahimmassa tapauksessa hitaammaksi tai jopa vääräksi. Joten ’ sinun on määritettävä omat neliö- ja kuutiofunktiosi. Ja silloinkin koodi olisi ruma kuin käyttää ** virtalähteenä.
  • @David Minun täytyy laittaa sulkeet kyllä, mutta älä ’ ei tarvitse toistaa lauseke useita kertoja ja paisuttaa lähdekoodia. Mikä vähentää luettavuutta paljon. Ja tavallinen alilausekkeiden eliminointi on mahdollista vain, jos kääntäjä voi taata, että ilmaisussa ei ole sivuvaikutuksia. Ja ainakin .net jitter ei ole ’ t liian älykäs tältä osin.

Vastaa

Java-kielen ja ydinkirjaston suunnittelijat päättivät sijoittaa suurimman osan matemaattisista operaatioista Math -luokkaan. Katso Math.pow () .

Miksi? Joustavuus priorisoida suorituskyky bittisignaalien tarkkuuden sijaan.Olisi vastoin muuta kielenkäyttöä sanomalla, että sisäänrakennettujen matemaattisten operaattoreiden käyttäytyminen voi vaihdella alustasta toiseen, kun taas Math-luokassa todetaan nimenomaisesti, että käyttäytyminen uhraa tarkkuutta suorituskyvyn vuoksi, joten ostajan on varottava:

Toisin kuin jotkut luokan StrictMath numeerisista menetelmistä, kaikki luokan vastaavien toimintojen toteutukset Matematiikkaa ei ole määritetty palauttamaan bitti-bittiä samat tulokset. Tämä rentoutuminen mahdollistaa paremmin suoritettavat toteutukset, joissa tarkkaa toistettavuutta ei vaadita.

Vastaus

Leviäminen oli osa Fortrania alusta alkaen, koska se oli suunnattu nimenomaan tieteelliseen ohjelmointiin. Insinöörit ja fyysikot käyttävät sitä usein simulaatioissa, koska voimalakisuhteet ovat yleisiä fysiikassa.

Pythonilla on vahva läsnäolo myös tieteellisessä laskennassa (esim. NumPy ja SciPy). Tämä viittaa eksponenttioperaattorinsa kanssa siihen, että se oli suunnattu myös tieteelliseen ohjelmointiin.

C, Java ja C # ovat juurtuneet järjestelmän ohjelmointiin. Ehkä tämä on vaikutus, joka piti eksponention pois tuettujen operaattorien ryhmästä.

Vain teoria.

Vastaa

C. C-koodi kirjoitettu koodipohja on yhteensopiva.

Java teki samoin, koska se ei halunnut pelotella olemassa olevia C ++ -ohjelmoijia.

Kommentit

  • Kun C luotiin, kertolasku ja jakaminen eivät puuttuneet harvoin laitteistosta ja ne oli toteutettava ohjelmistoissa. C: llä on kuitenkin kertolasku- ja jako-operaattoreita.
  • @siride: Tietojeni mukaan PDP-7: llä, joka oli ensimmäinen Unixia käyttävä tietokone, oli laitteistokerrointi ja -jako EAE: n kautta. Katso: bitsavers.org/pdf/dec/pdp7/F-75_PDP-7userHbk_Jun65.pdf

Vastaa

No, koska jokainen operaattori, jolla olisi järkevää virtaa, on jo käytössä. ^ on XOR ja ** määrittää osoittimen osoittimen. Joten sen sijaan heillä on vain toiminto, joka tekee saman. (kuten pow ())

Kommentit

  • @RTS – Etsikö langauge-kehittäjä todella järkeä enemmän kuin tehokkuutta?
  • Hyvä ohjelmointikielen kehittäjä tarkastelee molempia. En voi ’ sanoa mitään Javaista. Mutta c ++: ssa funktio pow () lasketaan kääntöhetkellä. Ja on yhtä tehokas kuin tavalliset operaattorit.
  • @RTS: pow() -funktio suorittaa laskennan ajon aikana, ellet saa kääntäjää, joka pystyy jatkuvasti taittamaan haulle pow(), jota epäilen kovasti. (Jotkut kääntäjät antavat sinulle mahdollisuuden käyttää laskimen suorittamiseen prosessorin sisäisiä ominaisuuksia.)
  • @Silicossa en tarkoittanut ’ t tarkoittavan, että se laskee lopullisen Arvo, tarkoitin, että kääntäjät optimoivat funktiokutsun pois, joten sinulla on vain raaka yhtälö.
  • @josefx: Varmasti se ’ on hyvä syy. Yksittäinen * on leksikaalinen tunnus, riippumatta siitä, käytetäänkö sitä ’ indirektioon tai kertomiseen. **, joka tarkoittaa eksponentointia, olisi joko yksi tai kaksi leksikaalista tunnusta, ja et todellakaan halua ’ halua, että lekserisi täytyy lyödä symboli taulukkoon merkitsemistä varten.

Vastaus

Tosiasia on, että aritmeettiset operaattorit ovat vain toimintojen pikavalintoja. (Lähes) Kaikki, mitä teet heidän kanssaan, voidaan tehdä toiminnolla. Esimerkki:

c = a + b; // equals c.set(a.add(b)); // or as free functions set(c, add(a,b)); 

Se on vain yksityiskohtaisempi, joten en näe mitään vikaa toimintojen käyttämisessä ”voiman” suorittamiseen.

Vastaus

Lisäys / vähennys / negaatio ja kertolasku / jako ovat matemaattisia perusoperaattoreita. Jos tekisit virran operaattoriksi, missä lopetat? Neliöjuuri operaattori? N-root-operaattori? Logaritmioperaattori?

En voi puhua heidän luojiensa puolesta, mutta voin sanoa, että mielestäni tällaisten operaattorien käyttäminen kielellä ei ole hankalaa eikä suorakulmaista. näppäimistöllä jäljellä olevien muiden kuin aakkosnumeeristen / välilyöntien merkkien määrä on melko rajallinen. Itse asiassa on outoa, että moduulioperaattori on C ++: ssa.

Kommentit

  • +1 – En ymmärrä miksi mod operaattorina on outoa. Se

div id = ”749f89ae7f”> s yleensä yksi käsky. Se ’ on primitiivinen operaatio kokonaisluvuilla. Se ’ käytetään eniten kaikkialla tietojenkäsittelytieteessä.(Rajoitettujen puskureiden toteuttaminen ilmanmodhaisee)

  • @Billy ONeal: Outoa, koska epäjohdonmukaisuus on mahdollista käyttää kokonaisluku- ja liukuluku-tyyppien kanssa . Ehdottomasti hyödyllinen, enkä ’ uneksisi sen poistamisesta. Vain omituinen on kaikki.
  • Vastaa

    Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *