koodaaja wrote:Northburns wrote:Ja tässä topikissa ei ole vielä tullut MIN()-kaavaa, joten tässäpä olisi:
Code: Select all
(a,b) //Parametrit
pienempi = b-(((a-b) Sar 31)=-1)*(b-a)
Onko tuossa mitään oleellista etua tähän nähden?
...
Etuhan on siinä, että jos kielessä tai kääntäjässä, jolla tuon toteuttaa löytyy binäärinen AND, niin pienemmän arvon valitsemisen voi toteuttaa ilman kertolaskua, vertailua ja hyppyjä (joista ensimmäinen ja kolmas ovat hitaita verrattuna ynnäämiseen ja maskaamiseen *).
Kun tuosta (a-b Sar 31) saadaan maski, joka on täynnä nollaa, jos a>b ja täynnä ykkösiä, jos a<b. Tällä AND-maskataan sitten b-a, ja b:stä vähennetään se. (jos a>b (maski ykkösiä-> vähennetään a-b), ja vähennetään nolla, kun b<a.
Mutta kuten sanottu, riippuu tosiaan ohjelmointikielestä, kääntäjästä ja alustasta, mikä on nopein. Kannattaa benchmarkata, ennen kuin valitsee. Ja tuo yksinkertainen Sar oli kivä löytää CB:stä, kun sitä ei mm. C-standardissa ole (vaikka onkin sama kuin perus shiftaus oikealle etumerkittömille, ja positiivisille luvuille). Tai voi jakaa 2^31:llä, mutta sitten kyllä mikä tahansa muu ratkaisu olisi parempi.
EDIT:Okei, testasin sitten nopeudet omalla koneella (niin minun kuin koodaajankin esittämät kaavat), niin CB:llä kuin MinGW:n kääntämällä C++:lla (ilman optimointeja luonnollisesti). Nopeimmiksi selvisivät CB:ssä CB:n oma MIN-funktio, ja C++:ssa (a<b?a:b). Muissa ei ollut merkittäviä eroja.
Olisin muuten postannut tulokset ja sorsat, mutta en voinut upata .txt, enkä .pdf tiedostoja, joten hmph... Evo tai tietoturva-kysymys.
Ja olisin voinut tähänkin postata, mutta se olisi mennyt liian off-topiciksi. Pysytään asiassa. Tää on hyvä topiikki.
*: Riippuu raudasta pitkälti tämäkin. Benchmarkkaus kannattaa.