Hozzászólások
-
SzerzőBejegyzés
-
Ha valakit érdekel: mellékelem a fentiekben említett doksi szerzõjének levelét ( írtam neki ):
„…
Yes, your program illustrates the same issue that was discussed in linux_numerics.txt on the web site. The program runs correctly under FreeBSD and 64-bit linux (Red Hat Enterprise 3 AMD64 version), but gives the wrong result when compiled for 32 bits under Red Hat Enterprise and almost certainly all other 32-bit Linux distributions.Here’s a version that runs correctly in 32-bits:
#ifdef __linux
#include
#endifint main(int argc, char * argv[]) {
double a,b,c;
#ifdef __linux
// This puts the X86 FPU in 64-bit precision mode. The default under
// Linux is to use 80-bit mode, which produces subtle differences from
// FreeBSD and other systems, eg, (int)(1000*atof(„0.3”)) is 300 in
// 64-bit mode, 299 in 80-bit mode.
fpu_control_t cw;
_FPU_GETCW(cw);
cw &= ~_FPU_EXTENDED;
cw |= _FPU_DOUBLE;
_FPU_SETCW(cw);
#endifa=65.13;
b=21160;
c=a*b;
printf („a=%lf, b=%lf, c=%lf, a*b=%lf „,a,b,c,(a*b));
if((a*b)!=c)
printf(„nWrong result!na:t%14.4fnb:t%14.4fnc:t%14.4fna*b:t%14.4fnn”,a
,b,c,(a*b));else
printf(„nGood result!na:t%1fnb:t%1fnc:t%1fnn”,a,b,c);
return 0;
}
Regards,Steve Whiteley
…”
Na pont ezt akartam épp javasolni! Mármint, hogy állítsd át a tizedes pont utáni kijelzett digitek számát, és egybõl látványosabb a dolog.
Magamnál kipróbáltam.
[align=right][snapback]126924[/snapback][/align]Ez akkor OK, kösz mindenkinek.
Viszont az adattáblával még mindig harcolok, nem akar összejönni két float típus ( adatbázis float ) szorzatának értékelése. Esetleg ha van valaki aki ebbe bele tud szólni ? Jelenleg talán a float(4) valamilyen megoldást ad, de igazán nem tudom ez meddig „tart”.most akkor normális eredmény kell vagy összehasonlítás??? 🙂
(amugy ne hasonlíts össze =-vel double vagy float számokat, ahogy a man és a doksi is írja)
[align=right][snapback]126905[/snapback][/align]Akkor hogyan ?
Mivel az alapproblémám az volt, hogy az értékek egy adattáblába kerülnek, ahova be van téve egy automatikus ellenõrzés, hogy a*b egyenlõ-e c-vel.
Az összehasonlítást és az értékkezelést sem lehet kikerülni, mind a kettõre szükség van.Az én megoldásom:
Code:int main(int argc, char * argv[]) {long double a,b,c;
a=65.13;
b=21160;
c=a*b;
printf („a=%Lf, b=%Lf, c=%Lf, a*b=%Lf „,a,b,c,(a*b));
if((long double)(a*b)!=c)
printf(„nMost hibáztam!na:t%L4.4fnb:t%L4.4fnc:t%L4.4fna*b:t%L4.4dnn”,a,b,c,(a*b));
else
printf(„nMost eltaláltam!na:t%Lfnb:t%Lfnc:t%Lfnn”,a,b,c);
return 0;
}gabor@ubuntu:/mnt/uhuhomehda3/gabor $ ./teszt
a=65.130000, b=21160.000000, c=1378150.800000, a*b=1378150.800000
Most eltal-Wfloat-equal
Warn if floating point values are used in equality comparisons.The idea behind this is that sometimes it is convenient (for the
programmer) to consider floating-point values as approximations to
infinitely precise real numbers. If you are doing this, then you
need to compute (by analyzing the code, or in some other way) the
maximum or likely maximum error that the computation introduces,
and allow for it when performing comparisons (and when producing
output, but thatâs a different problem). In particular, instead of
testing for equality, you would check to see whether the two values
have ranges that overlap; and this is done with the relational
operators, so equality comparisons are probably mistaken.
$ gcc t.c
$ ./a.outMost hibáztam!
a: 65.1400
b: 21160.0000
c: 1378362.4000
a*b: 1378362.4000$ gcc -fsingle-precision-constant t.c
$ ./a.outMost eltaláltam!
a: 65.1400
b: 21160.0000
c: 1378362.3871
-fsingle-precision-constant
Treat floating point constant as single precision constant instead
of implicitly converting it to double precision constant.
$ gcc -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.3.2/specs
Configured with: ../configure –prefix=/usr –mandir=/usr/share/man –infodir=/usr/share/info –enable-shared –enable-threads=posix –disable-checking –with-system-zlib –enable-__cxa_atexit –host=i386-redhat-linux
Thread model: posix
gcc version 3.3.2 20031022 (Red Hat Linux 3.3.2-1)
[align=right][snapback]126898[/snapback][/align]Kösz, de evvel szerintem még nem oldódott meg a probléma, mivel c értéke kissé eltér a normálistól ( nem merem azt írni, hogy a végeredménytõl, mert manapság az már nem tudható biztosan :-)) ).
Sajnos most én nem tudom kipróbálni az általam talált doksiban említett két módszert:
1)uzsolt: erre tudnál példát hozni? Elég meredeken hangzik, hogy a szorzás nem mindig
kommutatív :ph34r:
micsoda: akkor ennek:Code:int main(int argc, char * argv[]) {double a,b,c;
a=65.13;
b=21160;
c=a*b;
printf („a=%lf, b=%lf, c=%lf, a*b=%lf „,a,b,c,(a*b));
if((a*b)!=c)
printf(„nMost hibáztam!na:t%14.4fnb:t%14.4fnc:t%14.4fna*b:t%14.4fnn”,a,b,c,(a*b));
else
printf(„nMost eltaláltam!na:t%1fnb:t%1fnc:t%1fnn”,a,b,c);
return 0;
}a teljes kimenetét tudnád postolni? Nálam rendben van, de kíváncsi lennék. Valamint egy gcc -v -t is.
[align=right][snapback]126888[/snapback][/align]Kedves Mindenki !
Akkor mondok valamit: b*a -t próbáltad már? Nem feltétlenül biztos, hogy a szorzás kommutatív, amikor valami géppel számolsz.
[align=right][snapback]126886[/snapback][/align]Igen sõt a: (a*B) – c != 0 -t is.
Szerintem a c/c++ ezt inkább double-á konvertálja, mivel az ‘a’ változó olyan típusú (és a kiértékelési sorrend miatt).
A hiba tényleg a számábrázolásból adódik, és platform (mármint pl intel/motorola) és valószínûleg fordító függõ is. 🙂
[align=right][snapback]126880[/snapback][/align]Udv!
Code:printf(„nMost hibáztam!na:t%14.4fnb:t%14.4fnc:t%14.4fna*b:t%14.4fnn”,a,b,c,(a*b));szerintem a (a*B) kifejezes problemas. Ugyanis b=21160 (int). Nem lehet, hogy a kifejezest atkonvertalja int-re?
Ha hulyeseget mondok, szoljatok.Morzel
[align=right][snapback]126874[/snapback][/align]Szerintem itt nem lehet hülyeséget mondani amíg a megoldás nincs meg.
Az tény, ha két egész számmal végezzük a mûveletet akkor minden OK, viszont ha belép egy tört akkor van a hiba.Ez nekem uhu 1.2 alatt van, 3.3.4-es gcc-vel. Hogy hardverfüggõ, az nem valószínû, de nem tudom, mi lehet. Adattáblákhoz (sql) meg nem értek, szóval ezt a részét passzolom. Nálad mi a program kimenete?
[align=right][snapback]126872[/snapback][/align]Az, hogy Most hibáztam, tehát az a*b != c.
Hiba nincs. -
SzerzőBejegyzés
legutóbbi hsz