Pereiti prie turinio

C++ neteisingas atsakymas


Rekomenduojami pranešimai

Sveiki.

 

Sprendžiu klasikinę matematikos užduotį su C++:

 

Šachmatų išradėjas iš valdovo paprašė tokio atlygio: ant pirmo šachmatų lentos langelio padėti vieną grūdą, ant antro du, ant trečio keturis ir t.t. vis dvigubinant, kol bus užpildyti visi langeliai. Valdovas tik nusijuokė ir paliepė atseikėti grūdų. Kiek grūdų gaus šachmatų išradėjas? Lentoje yra 64 langeliai. Naudokite double duomenų tipą.

 

Nors knygoje parašytas atsakymas yra 18446744073709550000, internete suradau kad atsakymas turi būti 18446744073709551615. Tačiau mano parašyta programa pateikia vienu vienetu didesnį atsakymą, t.y. 18446744073709551616 :D Gal kas galėtų paaiškinti kodėl taip yra? Ar čia programa kažką daro ar aš blogai parašiau? :D

 

Ačiū.

 

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
   int nLangelis = 1;
   double nGrudai = 0;
   double nSuma = 0;
   for (;nLangelis <= 64;)
   {
       nGrudai = nGrudai * 2;
       if (nLangelis==1)
       {
           nGrudai++;
       }
       nSuma = nSuma + nGrudai;
       nLangelis++;
   }
   cout << "Sachmatu isradejas gaus " << fixed << setprecision(0) << nSuma << " grudu." << endl;
   return 0;
}

 

P.S. Šitame forume žmonės visada padeda, tad kai reikia pagalbos parašau čia. Ar nebūtų patogiau sukurti kokią C++ problemų temą kad neteršti forumo naujomis temomis? :)

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Pabandyk išvesti su visais skaičiais po kablelio. Gali būti, kad dėl floating point formato gauni ne visai tikslų variantą (pvz. .6 trumpmeninė dalis) ir dėl to tau apvalina į viršų, ne apačią. Naudok floor() funkciją.

 

Tą patvirtina mano bandymas python:

>>> print sum([2**i for i in range(0,64)])
18446744073709551615 # sveikųjų skaičių aritmetika – atsakymas geras

>>> print '%.f' % sum([2.0**i for i in range(0,64)])
18446744073709551616 # floating point – netikslu

Redagavo Silke
Nuoroda į pranešimą
Dalintis kituose puslapiuose

Pabandyk išvesti su visais skaičiais po kablelio. Gali būti, kad dėl floating point formato gauni ne visai tikslų variantą (pvz. .6 trumpmeninė dalis) ir dėl to tau apvalina į viršų, ne apačią. Naudok floor() funkciją.

 

Tą patvirtina mano bandymas python:

>>> print sum([2**i for i in range(0,64)])
18446744073709551615 # sveikųjų skaičių aritmetika – atsakymas geras

>>> print '%.f' % sum([2.0**i for i in range(0,64)])
18446744073709551616 # floating point – netikslu

 

Padariau kad atsakymą rašytų su keturiais skaičiais po kablelio, visi 0 :)

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Padariau kad atsakymą rašytų su keturiais skaičiais po kablelio, visi 0 :)

Kodas?

 

Oh, apsigavau... Tavo algoritmas tiesiog blogas :) Skaičiuoji 2^64, kai turi skaičiuoti (2^64)-1...

 

Paprasčiausiai grūdų skaičius yra 2^0 + 2^1 + ... + 2^63, o susumavus tai ir gaunasi (2^64) - 1 :)

 

int suma = 0;
int siame = 1;
for (int i = 0; i < 64; i++) {
       suma += siame;
       siame *= 2;
}

 

Arba tiesiog atimk vienetą iš savo rezultato.

Redagavo Silke
Nuoroda į pranešimą
Dalintis kituose puslapiuose

Kodas?

 

Oh, apsigavau... Tavo algoritmas tiesiog blogas :) Skaičiuoji 2^64, kai turi skaičiuoti (2^64)-1...

 

Paprasčiausiai grūdų skaičius yra 2^0 + 2^1 + ... + 2^63, o susumavus tai ir gaunasi (2^64) - 1 :)

 

int suma = 0;
int siame = 1;
for (int i = 0; i < 64; i++) {
       suma += siame;
       siame *= 2;
}

 

Arba tiesiog atimk vienetą iš savo rezultato.

 

Supratau, ačiū :)

Nuoroda į pranešimą
Dalintis kituose puslapiuose

O gal kas nutuokia kodėl ši mano programa nenori tiksliai skaičiuoti vidurkio? T.y. pvz. dviejų skaičių 9 ir 10 vidrukį rodo 9.00?

 

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{

   setlocale(LC_ALL,"Lithuanian");
   int nMokiniai;
   int nVisi=0;
   double nVidurkis;
   cout << "Įveskite mokinių skaičių: "; cin >> nMokiniai;
   int nUgis[nMokiniai];
   cout << endl << endl;
   for (int i=0; i<nMokiniai; i++)
   {
           cout << "Įveskite " << i+1 << " mokinio ūgį: "; cin >> nUgis[i]; cout << endl;
           nVisi = nVisi + nUgis[i];
   }
   nVidurkis = nVisi / nMokiniai;
   cout << endl << "Mokinių ūgių vidurkis: " << fixed << setprecision(2) <<nVidurkis << " cm." << endl;
   return 0;
}

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Nes dalini sveiką skaičių nVisi iš sveiko skaičiaus nMokiniai. Dalinant sveikuosius skaičius, gausi tik sveikąjį. Vieną iš veiksme dalyvaujančių skaičių paversk į trumpeninį prieš dalindamas.

nVidurkis = nVisi / ((double)nMokiniai);

 

Ačiū! :)

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Prisijunkite prie diskusijos

Jūs galite rašyti dabar, o registruotis vėliau. Jeigu turite paskyrą, prisijunkite dabar, kad rašytumėte iš savo paskyros.

Svečias
Parašykite atsakymą...

×   Įdėta kaip raiškusis tekstas.   Atkurti formatavimą

  Only 75 emoji are allowed.

×   Nuorodos turinys įdėtas automatiškai.   Rodyti kaip įprastą nuorodą

×   Jūsų anksčiau įrašytas turinys buvo atkurtas.   Išvalyti redaktorių

×   You cannot paste images directly. Upload or insert images from URL.

Įkraunama...
  • Dabar naršo   0 narių

    Nei vienas registruotas narys šiuo metu nežiūri šio puslapio.

  • Prisijunk prie bendruomenės dabar!

    Uždarbis.lt nariai domisi verslo, IT ir asmeninio tobulėjimo temomis, kartu sprendžia problemas, dalinasi žiniomis ir idėjomis, sutinka būsimus verslo partnerius ir dalyvauja gyvuose susitikimuose.

    Užsiregistruok dabar ir galėsi:

    ✔️ Dalyvauti diskusijose;

    ✔️ Kurti naujas temas;

    ✔️ Rašyti atsakymus;

    ✔️ Vertinti kitų žmonių pranešimus;

    ✔️ Susisiekti su bet kuriuo nariu asmeniškai;

    ✔️ Naudotis tamsia dizaino versija;

    ir dar daugiau.

    Registracija trunka ~30 sek. ir yra visiškai nemokama.

  • Naujausios temos

  • Karštos temos

×
×
  • Pasirinkite naujai kuriamo turinio tipą...