Portál AbcLinuxu, 13. května 2025 22:02
#include <float.h> #include <stdio.h> int main(int argc, char* argv[]) { double eps=1.0; while(1) { eps=eps/2.0; if( (1.0 + (eps/2.0)) == 1.0 ) break; } printf("vypocitane eps= %.67f\n",eps); printf("konstanta DBL = %.67f\n",DBL_EPSILON); return 0; }pod gentoo 32bit vysledok je :
32bit Linux OS 0.00000000000000000010842021724855044340074528008699417114257812500 -vypocitane eps 0.00000000000000022204460492503130808472633361816406250000000000000 -konstanta DBL_EPSILONa pod gentoo 64bit vysledok je :
0.00000000000000022204460492503130808472633361816406250000000000000 -vypocitane eps 0.00000000000000022204460492503130808472633361816406250000000000000 -konstanta DBL_EPSILONnemalo by byt pod 64bit strojove epsilon mensie ako pod 32bit?
double eps=1.0;
double jedna=1.0;
double dva=2.0;
while(1)
{
eps=eps/dva;
if( (jedna + (eps/dva)) == jedna ) break;
}
Schvalne, co to spocita takhle.
-S
). Zatímco 32-bitová verze používá registry koprocesoru a nechává koprocesor provést i porovnání, 64-bitová pracuje s registry %xmm0
a spol. Problém je pravděpodobně v tom, že koprocesor interně pracuje s vyšší přesností, než jakou následně prezentuje ven (pokud si dobře vzpomínám, interně koprocesor pracuje s 96-bitovými hodnotami, zatímco typ long double
je pouze 64-bitový). Tomu by nasvědčovala i skutečnost, že pokud si výraz (1.0 + (eps/2.0))
necháte uložit do proměnné a tu porovnáte s jedničkou, vyjde vám to na obou platformách stejně.
Aneb další příklad na známý poznatek, že porovnávat reálná čísla na rovnost znamená koledovat si o naprosto nedeterministické chování programu.
double
je pouze 64-bitový", což je pravda (pro gcc 4.0.2) ve 32-bitové i 64-bitové verzi. Typ long double
je různý: s -m32
96-bitový a s -m64
128-bitový.
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.