Delenie 2 float-ov – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Delenie 2 float-ov – C / C++ – Fórum – Programujte.comDelenie 2 float-ov – C / C++ – Fórum – Programujte.com

 

lukas.balaz0
Super člen
12. 11. 2014   #1
-
0
-

Čaute

V živote som printf nepoužíval, ale v zadaní toho, čo teraz robím, sa vyžaduje používať printf a vypisovať formátom %.10g (tiež tomu moc nechápem). Na konci programu mám 2 int-y, ktoré mám vydeliť a takto vypísať.

Pri testovaní som tam mal čísla 10250367 a 18. Po vydelení mi vypísalo 569464.8125, pričom na google a windows kalkulačke mi vyhodilo 569464.83333. Keď som na kalkulačke vynásobil 569464.8125*18, vyšlo 10250366.625. A keď som spustil jednoduchý program:
 

#include <cstdio>
using namespace std;
int main()
{
	int a=10250367;
	int b=18;
	printf("%.10g\n",(float)a/(float)b);
	float c=(float)a/(float)b;
	printf("%.10g\n",c);
	printf("%.10g\n",c*(float)b);
}


výstup bol:

569464.8125
569464.8125
10250367


A teraz neviem či som ja debil a neviem používať kalkulačku, alebo sa môj komp pomýli pri delení 10 miliónov dvoj-ciferným číslom už na druhom desatinnom mieste. Veď to by vôbec nemal byť problém dokonca aj s float-om nie ??

Nahlásit jako SPAM
IP: 80.242.41.–
12. 11. 2014   #2
-
0
-

Zkus místo float použít double. 

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:b168:39...–
lukas.balaz0
Super člen
12. 11. 2014   #3
-
0
-

#2 hlucheucho
Áno jasné, double funguje, len ja som si myslel, že ten formát výpisu funguje len pre float, teraz som trochu pogooglil a zistil som, že nie. Tak teda čo znamená to %.10g a ako je možné, že tam nie je jasne určený typ premennej (ako som písal, moc sa do toho nerozumiem, ale myslím, že aj na int a long long sú rôzne formáty a musí to byť jasne určené) ?

Urobil som ešte jeden malý test ... a výsledok ma celkom prekvapil:

#include <cstdio>
using namespace std;
int main()
{
	int a=10250367;
	int b=18;
	printf("%.10g\n",(double)a/(double)b);
	double d=(double)a/(double)b;
	printf("%.10g\n",d);
	float c=d;
	printf("%.10g\n",c);
	printf("%.10g\n",c*(double)b);
}

vystup:
569464.8333
569464.8333
569464.8125
10250366.62


WAAAT ?? Prečo keď sa float prepytuje na double tak sa úplne zmení hodnota ?

Nahlásit jako SPAM
IP: 80.242.41.–
12. 11. 2014   #4
-
0
-

float má horší přesnost, má na to méně bitů než double. %.10g určuje max. počet platných číslic, které to tiskne. Když dáš %.8g, u tvého čísla napíše jen dvě des. místa.

Jinak ty specifikátory formátu bys měl používat přesně. Vyhneš se tím chybám způsobeným "neochotou" překladače přetypovat a chybám způsobeným chybnou interpretací dat. V případě int a long jsem si na tom jednou vylámal zuby. V případě f se uvádí Decimal floating point, což je float i double.

podrobnosti najdeš např. na http://www.cplusplus.com/reference/cstdio/printf/  Chce si to s tím trochu pohrát.

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:b168:39...–
vitamin+8
Grafoman
12. 11. 2014   #5
-
0
-
Nahlásit jako SPAM
IP: 195.28.77.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Ovrscout
~ Anonymní uživatel
113 příspěvků
12. 11. 2014   #6
-
0
-

#3 lukas.balaz
Pokud jde o funkce s proměnným počtem parametrů jako třeba printf je float hodnota "vždy" přetypována/překonvertována na double a pak teprve předána do té funkce, přkladač to dělá automaticky a nelze se tomu vyhnout, vychází to z normy pro céčko. Z toho vyplývá že specifikátory %g a %f  pracují pouze s typem double. Teoreticky se pak může stát že při konverzi z floatu na double dostanete trochu jiné čislo.

Prakticky je třeba vědět na kolik počet desetinných bylo číslo zadáno,/změřeno/spočítáno, nebo na kolik desetinných míst se má zobrazit. Ta automatika se totiž v některých případech může chovat dost divně, protože určit počet platných míst z neceločíselné hodnoty uložené jako float/double není tak jednoduché jak se zdá. Hlavní problém je že číslo není uloženo s desetinnou čárkou ale s "dvojkov-nou" čárkou (čárka v zápise ve dvojkové soustavě).

Na hraní jsou dostupné online nástroje jako třeba http://www.h-schmidt.net/…IEEE754.html
Schválně si zkuste vyplnit čísla 0.1 a  1000000.1 :)

Nahlásit jako SPAM
IP: 193.165.79.–
Ovrscout
~ Anonymní uživatel
113 příspěvků
12. 11. 2014   #7
-
0
-

#6 Ovrscout
ještě doplním sám sebe :)

v určitých případech se i při počítání s float/double může stát že hodnota výpočtu je jakoby přesnější nebo odlišná než odpovídá ručnímu přepisu/přepočtu. Fígl může být ukryt v tom že procesory (často) nepočítají ve float/double ale mají mají hodnotu uloženou ve více bitech (třeba 80bit proti 64bit v double) a když to překladač řádně zaoptimalizuje (a nebo taky nezoptimalizuje) může být výsledek překvapující. Čili pak už jen zbývá debugovat až do asembleru a zobrazovat si hodnoty v hexa místo promocí prinf :)

Jinak dobrou (ale jen orientační) pomúckou je uvažovat počet platných dekadických číslic, např pro float je to 7(7.2) a pro double 15(15.95).   např ve floatu je číslo 9`999`999, nebo 99`999`900 je v pohodě ale 9`999`999.1 nebo 99`999`999 už se dobře uložit nedá. Je to ale jen orientační, zkuste si třeba číslo 1E10 a 1E11 (v tom online konvertoru).

Nahlásit jako SPAM
IP: 193.165.79.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 84 hostů

Podobná vlákna

Delenie C — založil

Aké delenie ? — založil Michal Vrábel

Delenie v PHP — založil Anonymní uživatel

Delenie s double - c++ — založil lukas.balaz

Delenie celeho AX — založil andy

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý