Pereiti prie turinio

c++ vietoj 0 atvaizduoja -3.27826e-008


Rekomenduojami pranešimai

Sveiki gavau užduotį padaryti programą kuri skaičiuotų y=1/sqrt(x-a) sumą, tuo pačiu atvaizduoti viską lentelėje, niekaip nesuprantu kodėl vietojė X reikšmės kai yra lygi 0 man atvaizduoja -3.27826e-008 ?

#include "stdafx.h"
#include<iostream>
#include<conio.h>
#include<math.h>
#include<iomanip>
using namespace std;
void main() {
int a;
float x,y,sum;
y=0;sum=0;
cout<<"|    x    |    a    |    y    |"<<endl;
cout<<"|---------|---------|---------|"<<endl;
for(x=-1;x<=1;x=x+0.2) {
for(a=-4;a<=0;a=a+2) {
if (x-a<=0) {
y=0;
}
else
y=1/sqrtf(x-a);
sum=sum+y;
cout<<"|  "<<setw(4)<<x<<"   |"<<setw(9)<<a<<"|"<<setw(9)<<y<<"|"<<endl; }
}
cout<<"-------------------------------"<<endl;
cout<<"Y suma lygi "<<sum;

getch();
}

Vygdant programą atsakymas toks

|    x    |    a    |    y    |
|---------|---------|---------|
|    -1   |       -4|  0.57735|
|    -1   |       -2|        1|
|    -1   |        0|        0|
|  -0.8   |       -4| 0.559017|
|  -0.8   |       -2| 0.912871|
|  -0.8   |        0|        0|
|  -0.6   |       -4| 0.542326|
|  -0.6   |       -2| 0.845154|
|  -0.6   |        0|        0|
|  -0.4   |       -4| 0.527046|
|  -0.4   |       -2| 0.790569|
|  -0.4   |        0|        0|
|  -0.2   |       -4| 0.512989|
|  -0.2   |       -2| 0.745356|
|  -0.2   |        0|        0|
|  -3.27826e-008   |       -4|      0.5|
|  -3.27826e-008   |       -2| 0.707107|
|  -3.27826e-008   |        0|        0|
|   0.2   |       -4|  0.48795|
|   0.2   |       -2|   0.6742|
|   0.2   |        0|  2.23607|
|   0.4   |       -4| 0.476731|
|   0.4   |       -2| 0.645497|
|   0.4   |        0|  1.58114|
|   0.6   |       -4| 0.466252|
|   0.6   |       -2| 0.620174|
|   0.6   |        0|  1.29099|
|   0.8   |       -4| 0.456435|
|   0.8   |       -2| 0.597614|
|   0.8   |        0|  1.11803|
|     1   |       -4| 0.447214|
|     1   |       -2|  0.57735|
|     1   |        0|        1|
-------------------------------
Y suma lygi 20.8954

Nuoroda į pranešimą
Dalintis kituose puslapiuose

tiesiog naudojant įprastus kintamųjų tipus (float, double) negaunama labai tiksli reikšmė. Pamėgink sukant ciklą daryti palyginimus, pvz:

 

if (x == -0.8){cout << "test";}

vietoj -0.8 parašyk keletą reiksmių, kurias turėtų įgyti kintamasis x ir pamatysi, jog maždaug po keleto ciklo iteracijų palyginimo sąlyga nebebus tenkinama, ir žodis "test" nebebus spausdinamas. Tad dirbti su realiaisiais skaičiais išties yra gana keblu. Norint išlaikyti tikslumą, reikia naudoti decimal tipą, tačiau, kaip C++ jį naudoti aš nežinau. Pamėgink pasidomėti ir turėtų pavykti :)

Nuoroda į pranešimą
Dalintis kituose puslapiuose

tiesiog naudojant įprastus kintamųjų tipus (float, double) negaunama labai tiksli reikšmė. Pamėgink sukant ciklą daryti palyginimus, pvz:

 

if (x == -0.8){cout << "test";}

vietoj -0.8 parašyk keletą reiksmių, kurias turėtų įgyti kintamasis x ir pamatysi, jog maždaug po keleto ciklo iteracijų palyginimo sąlyga nebebus tenkinama, ir žodis "test" nebebus spausdinamas. Tad dirbti su realiaisiais skaičiais išties yra gana keblu. Norint išlaikyti tikslumą, reikia naudoti decimal tipą, tačiau, kaip C++ jį naudoti aš nežinau. Pamėgink pasidomėti ir turėtų pavykti :)

Aš suprantu, jei tai būtų kažkokie tai skaičiavimai labai tikslūs ir po kablelio neralūs dideli skaičiai, bet kodėl tokiu atveju(juk čia paprastas ciklas nuo -1 iki 1 , žingsniu 0,2 ir 0 atveju bardagas , juk float čia pilnai tinka ...

Redagavo apci
Nuoroda į pranešimą
Dalintis kituose puslapiuose

Mėginau pasinagrinėti kas čia per nesamonę, neradęs paklausiau grupiokų. Tai paaiškino truputi ir parodė kaip išspręsti problemą :)

 

Sprendimas:

float x;

for(x=-0.4;x<=0.4;x+=0.2)

cout << (fabs(x) < 1e-6 ? 0 : x) << endl;

 

 

Dėkui padėjo, o kame reikalas su tuo 0 ?

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Paaiškinimas:

CPU operuoja dvejetainiais skaičiais ir ne visus dešimtainius skaičius galima atvaizduoti visiškai tiksliai dvejetainėje sistemoje.

Tai gaunasi minimalios paklaidos.

 

Geriausiai būtų vengti float skaičių ir tiek, tuomet ir nesamonių nebūtų :)

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Taip, kaip ir kiti sakė, float kompiuteriuose yra netikslūs. Lygiai taip, kaip negali dešimtainėje tiksliai atvaizduoti 1/3, taip dešimtainėje kai kurių skaičių.

 

Ir, kiek ieškau, C++ stdlib'e net neturi funkcijos suapvalinti float'ams iki tam tikro dešimtainių skaitmenų skaičiaus po kablelio, bet idėjų gali pasisemti čia. http://stackoverflow.com/questions/1343890/rounding-number-to-2-decimal-places-in-c .

 

Jei nufloorinęs iki kokių penkių-šešių dešimtainių vietų gauni 0, tai manau, kad gali drąsiai laikyt, kad ten nulis ir yra :)

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Geriausias patarimas yra vengti float tipo iki tol, kol jis neišvengiamas. Todėl kadangi i žingsnis diskretus (0,2), tai tiesiog i pereini nuo -10 iki 10 (-10:2:10) ir kitose vietose atitinkamai į tai atsižvelgi. Tada būtų patogu a ir pasidauginti iš dešimt, o y formulėje i ir a skirtumą padalinti iš 10.

 

O esmė tokia, kad float negali niekaip atvaizduoti 0,2. Tiksliai jis atvaizduoja tik skaičius, kurie gali būti užrašyti 2-b, kur b priklauso natūraliems, jų sumas bei nulį. Kadangi float turi baigtinį skaičių bitų informacijai saugoti, tai 0,2 išeina tik apytiksliai.

 

0,2 → dvejatainisdešimtainis

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Geriausias patarimas yra vengti float tipo iki tol, kol jis neišvengiamas. Todėl kadangi i žingsnis diskretus (0,2), tai tiesiog i pereini nuo -10 iki 10 (-10:2:10) ir kitose vietose atitinkamai į tai atsižvelgi. Tada būtų patogu a ir pasidauginti iš dešimt, o y formulėje i ir a skirtumą padalinti iš 10.

 

O esmė tokia, kad float negali niekaip atvaizduoti 0,2. Tiksliai jis atvaizduoja tik skaičius, kurie gali būti užrašyti 2-b, kur b priklauso natūraliems, jų sumas bei nulį. Kadangi float turi baigtinį skaičių bitų informacijai saugoti, tai 0,2 išeina tik apytiksliai.

 

0,2 → dvejatainisdešimtainis

 

Nužudiai savo išsamiu ir suprantamu atsakymu :)

Taigi kodas galutinis toks

#include "stdafx.h"
#include<iostream>
#include<conio.h>
#include<math.h>
#include<iomanip>
using namespace std;
void main() {
int a;
float x,y,sum;
y=0;sum=0;
cout<<" ----------------------------- "<<endl;
cout<<"|    x    |    a    |    y    |"<<endl;
cout<<"|---------|---------|---------|"<<endl;
for(x=-10;x<=10;x=x+2) {
for(a=-40;a<=0;a=a+20) {
if (x-a<=0) {
y=0;
}
else
y=1/sqrtf((x-a)/10);
sum=sum+y;
cout<<"|  "<<setw(4)<<x/10<<"   |"<<setw(5)<<a/10<<"    |"<<setw(9)<<y<<"|"<<endl; }
}
cout<<" -----------------------------"<<endl;
cout<<"    Y suma lygi "<<sum;

getch();
}

Ir atsakymas tvarkingas

-----------------------------
|    x    |    a    |    y    |
|---------|---------|---------|
|    -1   |   -4    |  0.57735|
|    -1   |   -2    |        1|
|    -1   |    0    |        0|
|  -0.8   |   -4    | 0.559017|
|  -0.8   |   -2    | 0.912871|
|  -0.8   |    0    |        0|
|  -0.6   |   -4    | 0.542326|
|  -0.6   |   -2    | 0.845154|
|  -0.6   |    0    |        0|
|  -0.4   |   -4    | 0.527046|
|  -0.4   |   -2    | 0.790569|
|  -0.4   |    0    |        0|
|  -0.2   |   -4    | 0.512989|
|  -0.2   |   -2    | 0.745356|
|  -0.2   |    0    |        0|
|     0   |   -4    |      0.5|
|     0   |   -2    | 0.707107|
|     0   |    0    |        0|
|   0.2   |   -4    |  0.48795|
|   0.2   |   -2    |   0.6742|
|   0.2   |    0    |  2.23607|
|   0.4   |   -4    | 0.476731|
|   0.4   |   -2    | 0.645497|
|   0.4   |    0    |  1.58114|
|   0.6   |   -4    | 0.466252|
|   0.6   |   -2    | 0.620174|
|   0.6   |    0    |  1.29099|
|   0.8   |   -4    | 0.456435|
|   0.8   |   -2    | 0.597614|
|   0.8   |    0    |  1.11803|
|     1   |   -4    | 0.447214|
|     1   |   -2    |  0.57735|
|     1   |    0    |        1|
-----------------------------
   Y suma lygi 20.8954

Redagavo apci
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ą...