Portál AbcLinuxu, 8. května 2025 06:50

Dotaz: GCC bug u IEEE 754?

8.1.2011 18:09 Rekes
GCC bug u IEEE 754?
Přečteno: 439×
Odpovědět | Admin
Nazdar, pomozte mi urcit jestli jde o gcc bug.
#include <iostream>

int main(int argc, char **argv) {
	unsigned long int c = 0;
	float t = 0;
	
	while (t < 3000) {
		if (c % 1000000 == 0) {
			std::cout << t << "\n";
		}
		
		c++;
		t += 0.0001;
	}
	
	return 0;
}

Kompilace g++ -ansi -Wall -pedantic test.cpp -o test

Cyklus by mel pridavat k float promenne t konstantu 1e-4 dokud t nedosahne hodnoty 3000. To se vsak nestane, protoze hodnota t se zastavi na cisle 2048 a dal nejde (i kdyz je inkrementovana, zustava konstantni). Tato limitni hodnota roste s krokem, napr. pro krok 1e-3 se inkrementace zastavi az na 32768, pro 1e-2 to je 262144.

What gives?
Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

8.1.2011 18:13 Rekes
Rozbalit Rozbalit vše Re: GCC bug u IEEE 754?
Odpovědět | | Sbalit | Link | Blokovat | Admin
Jeste bych dodal, ze toho chovani pozoruji na gcc version 4.4.4 (Gentoo 4.4.4-r2 p1.2, pie-0.4.5) na jadre 2.6.36.
stativ avatar 8.1.2011 18:18 stativ | skóre: 54 | blog: SlaNé roury
Rozbalit Rozbalit vše Re: GCC bug u IEEE 754?
Odpovědět | | Sbalit | Link | Blokovat | Admin
To není bug, to je feature :-) nebo lépe vlastnost IEEE754. Nechce se mi to počítat, nicméně jde o to, že pro hodnotu 1E-4 máš exponent -14 a pro hodnotu 2048 máš exponent 11. Když sečítáš floaty, tak je nejdřív převedeš na ten větší exponent (v tomhle případě 11) a mantisu menšího posuneš doprava. Pro 1E-4 tu mantisu posuneš o 25 míst do prava. Problém je v tom, že mantisa má 24 bitů (nepočítám implicitní 1) a tudíž bude pro hodnotu 1E-4 nulová => přičítáš nulu.
Ať sežeru elfa i s chlupama!!! ljirkovsky.wordpress.com stativ.tk
stativ avatar 8.1.2011 18:20 stativ | skóre: 54 | blog: SlaNé roury
Rozbalit Rozbalit vše Re: GCC bug u IEEE 754?
mantisa má samozřejmě 23 bitů.
Ať sežeru elfa i s chlupama!!! ljirkovsky.wordpress.com stativ.tk
stativ avatar 8.1.2011 18:22 stativ | skóre: 54 | blog: SlaNé roury
Rozbalit Rozbalit vše Re: GCC bug u IEEE 754?
No to jsem tomu pomohl. Mantisa je ukládaná na 23 bitech. S implicitní 1 na začátku to dává 24 bitů.

To mám z toho, že půlku věty upravím a zapomenu opravit i tu druhou.
Ať sežeru elfa i s chlupama!!! ljirkovsky.wordpress.com stativ.tk
8.1.2011 18:23 rastos | skóre: 63 | blog: rastos
Rozbalit Rozbalit vše Re: GCC bug u IEEE 754?
Odpovědět | | Sbalit | Link | Blokovat | Admin

No a nebude to tým, že číslo 2048.0001 nie je možné reprezentovať dátovým typom float?

Pohraj sa na http://www.h-schmidt.net/FloatApplet/IEEE754.html

binárne 01000101000000000000000000000000 je float 2048.0
binárne 01000101000000000000000000000001 je float 2048.0002

8.1.2011 18:25 Jirka P
Rozbalit Rozbalit vše Re: GCC bug u IEEE 754?
Odpovědět | | Sbalit | Link | Blokovat | Admin
O bug nejde.

Ty jsi vpodstatě experimentálně ověřil, že typ float má u tebe zhruba 24bitovou mantisu (2048*10^4 ~ 2^24).

To, že v číslech s plovoucí řádovou čárkou platí, že a+b==a pokud b<epsilon/2*a je docela normální. Spíš mě překvapuje, že to neví někdo, kdo o IEEE754 evidentně ví.
8.1.2011 20:50 Šangala | skóre: 56 | blog: Dutá Vrba - Wally
Rozbalit Rozbalit vše Re: GCC bug u IEEE 754?
Odpovědět | | Sbalit | Link | Blokovat | Admin
97 klíčových znalostí programátora strana 84, kapitola „Čísla s plovoucí řádovou čárkou nejsou reálná.
To, že trpíš stihomamem, ještě neznamená, že po tobě nejdou. ⰞⰏⰉⰓⰀⰜⰉ ⰗⰞⰅⰜⰘ ⰈⰅⰏⰉ ⰒⰑⰎⰉⰁⰕⰅ ⰏⰉ ⰒⰓⰄⰅⰎ ·:⁖⁘⁙†
Saljack avatar 8.1.2011 21:48 Saljack | skóre: 28 | blog: Saljack | Praha
Rozbalit Rozbalit vše Re: GCC bug u IEEE 754?
Je ta knížka dobrá? Vypadá to celkem zajímavě.
Sex, Drugs & Rock´n Roll.
8.1.2011 22:52 Šangala | skóre: 56 | blog: Dutá Vrba - Wally
Rozbalit Rozbalit vše Re: GCC bug u IEEE 754?
No asi za přečtení stojí, ale asi tak jako většina knížek - není to žádná sláva.
C++ 101 programovacích technik je levnější a je rozhodně zajímavější (ale také se zabývá malinko jiným tématem). :)
To, že trpíš stihomamem, ještě neznamená, že po tobě nejdou. ⰞⰏⰉⰓⰀⰜⰉ ⰗⰞⰅⰜⰘ ⰈⰅⰏⰉ ⰒⰑⰎⰉⰁⰕⰅ ⰏⰉ ⰒⰓⰄⰅⰎ ·:⁖⁘⁙†
10.1.2011 11:51 Šangala | skóre: 56 | blog: Dutá Vrba - Wally
Rozbalit Rozbalit vše Re: GCC bug u IEEE 754?
Odpovědět | | Sbalit | Link | Blokovat | Admin
Ještě mně to nedalo:
Zjednodušeně se nad typy float/double/long double dá přemýšlet takto, to jsou jejich obecné limity: Jinak když si následující zkompilujete (g++ -o inforeal inforeal.cpp ) a spustíte dostanete základní informace:
#include <iostream>
#include <float.h>

int main(int argc, char **argv) {
  std::cout.precision(FLT_DIG);
  std::cout.flags(std::ios::scientific);
  std::cout << "float:" << std::endl;
  std::cout << "              min: " << FLT_MIN << std::endl;
  std::cout << "              max: " << FLT_MAX << std::endl;
  std::cout << "  10 exponent min: " << FLT_MIN_10_EXP << std::endl;
  std::cout << "  10 exponent max: " << FLT_MAX_10_EXP << std::endl;
  std::cout << "           digits: " << FLT_DIG << std::endl;
  std::cout << "          Epsilon: " << FLT_EPSILON << std::endl;


  std::cout.precision(DBL_DIG);
  std::cout << "double:" << std::endl;
  std::cout << "              min: " << DBL_MIN << std::endl;
  std::cout << "              max: " << DBL_MAX << std::endl;
  std::cout << "  10 exponent min: " << DBL_MIN_10_EXP << std::endl;
  std::cout << "  10 exponent max: " << DBL_MAX_10_EXP << std::endl;
  std::cout << "           digits: " << DBL_DIG << std::endl;
  std::cout << "          Epsilon: " << DBL_EPSILON << std::endl;

  std::cout.precision(LDBL_DIG);
  std::cout << "long double:" << std::endl;
  std::cout << "              min: " << LDBL_MIN << std::endl;
  std::cout << "              max: " << LDBL_MAX << std::endl;
  std::cout << "  10 exponent min: " << LDBL_MIN_10_EXP << std::endl;
  std::cout << "  10 exponent max: " << LDBL_MAX_10_EXP << std::endl;
  std::cout << "           digits: " << LDBL_DIG << std::endl;
  std::cout << "          Epsilon: " << LDBL_EPSILON << std::endl;

#if defined FLT_ROUNDS
  std::cout << std::endl;
  std::cout << "Type of rounding floating numbers: ";
  switch(FLT_ROUNDS){
    case -1 : std::cout << "indeterminable"; break;
    case  0 : std::cout << "towards zero"; break;
    case  1 : std::cout << "to the nearest number"; break;
    case  2 : std::cout << "towards positive infinity"; break;
    case  3 : std::cout << "towards negative infinity"; break;
    default : std::cout << "? - no standard definition"; break;
  }
  std::cout << std::endl;
#endif

  return 0;
}
To, že trpíš stihomamem, ještě neznamená, že po tobě nejdou. ⰞⰏⰉⰓⰀⰜⰉ ⰗⰞⰅⰜⰘ ⰈⰅⰏⰉ ⰒⰑⰎⰉⰁⰕⰅ ⰏⰉ ⰒⰓⰄⰅⰎ ·:⁖⁘⁙†

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.