Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Lähimpään satalukuun pyöristäminen ei onnistu

iksu [27.06.2010 23:06:42]

#

Tämmöinen pienimuotoinen ongelma pyöristämisestä.

Eli miksi tuo testi -muuttuja antaa lopputulokseksi 1357, mutta testi2 antaa halutun (1300) tasaluvun? Laskutoimitukset ovat sinällään ihan samat tietääkseni...

Jälkeenpäin tosin opin että pyöristämiseen on myös olemassa valmiita keinoja, mutta päätimpä kysyä silti.

#include <iostream>

int main() {
int testi = 1234;
testi = ((testi * 1.1) / 100) * 100; // mikä tässä on vikana?
std::cout << testi << std::endl; // tulostaa 1357

int testi2 = 1234;
testi2 = testi2 * 1.1;
testi2 = testi2 / 100;
testi2 = testi2 * 100;
std::cout << testi2 << std::endl; //tulostaa 1300
}

edit: testattu ubuntu 9.10 ja siinä olevalla g++ kääntäjällä.

Antti Laaksonen [27.06.2010 23:19:02]

#

Ensimmäisessä tapauksessa väliarvot ovat liukulukuja ja vain lopputulos muutetaan kokonaisluvuksi. Vaikka muuttuja testi on kokonaisluku, sen kertominen liukuluvulla muuttaa tyypin liukuluvuksi. Toisessa tapauksessa taas jokainen väliarvo muutetaan kokonaisluvuksi.

Tarvittaessa tyyppiä voi muuttaa itse seuraavaan tapaan:

testi = (int)((testi * 1.1) / 100) * 100;

iksu [27.06.2010 23:32:09]

#

Ongelmahan tuli alunperin siitä, että olin jo SDL testeissä käyttänyt samanlaista taktiikkaa ristinollan tekemiseen.

Eli:
hiiri_x = (event.button.x / 200) * 200

Pelikentän koko oli 600x600. Luin hiiri_x muuttujaan hiiren x-sijainnin jaettuna 200, jolloin sain arvon 0, 1 tai 2. Eli jos hiiren x koordinaatti oli kohdass 300, niin 300/200 tuotti pelille arvon 1.

Sitten kerroin tuon arvon 200, jolloin tiesin mihin kohtaan piirtäminen piti suorittaa. Eli esimerkkitapauksessa piirtäminen aloitettiin kohdasta 200.

Ovatko nämä tilanteet nyt jotenkin samanlaiset/erilaiset vai miksi ei vaan pieni pää tajua missä vika :) ?

Antti Laaksonen [27.06.2010 23:45:22]

#

Ilmeisesti event.button.x on kokonaisluku, jolloin tilanne on erilainen. Kun kokonaisluku (event.button.x) jaetaan kokonaisluvulla (200), myös lopputulos on kokonaisluku. Mutta kun liukuluku (testi * 1.1) jaetaan kokonaisluvulla (100), lopputulos on liukuluku.

Tässä on vielä yksi tapa toteuttaa pyöristys:

testi = testi * 1.1;
testi = (testi / 100) * 100;

iksu [27.06.2010 23:59:58]

#

Jees, tuo selkeyttää asiaa melkoisesti.

Kiitokset.

User137 [28.06.2010 11:23:23]

#

testi = testi * 1.1;

voi myös kirjoittaa kokonaislukuina jottei muunnosta tarvita

testi = testi * 11 / 10;

Grez [28.06.2010 18:18:45]

#

Kannattaa myös huomata, että useimmat (jos yksikään) esitetyistä tavoista ei pyöristä lähimpään satalukuun.

User137:n esimerkkiä mukaellen:

testi = ((testi * 11 + 500) / 1000) * 100;

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta