/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
sammenligning ?
Fra : Lasse Madsen


Dato : 22-02-04 23:53

Hej jeg har lige et hurtigt spørgsmål ...

Findes der nogle regler i C om håndtering af floats i IF sætninger og
sammenligninger mod andre data typer feks char's int's long's etc. ?

if ( (float)x > 12.223 )

if ( (float)x == (char)11 )

if ( (float)x != (long)1251515L )

osv...

M.v.h
Lasse Madsen



 
 
Bertel Brander (23-02-2004)
Kommentar
Fra : Bertel Brander


Dato : 23-02-04 00:29

Lasse Madsen wrote:
> Hej jeg har lige et hurtigt spørgsmål ...
Jeg er bange for at svaret ikke er lige så hurtigt
>
> Findes der nogle regler i C om håndtering af floats i IF sætninger og
> sammenligninger mod andre data typer feks char's int's long's etc. ?
Ja.
>
> if ( (float)x > 12.223 )
Her vil jeg mene at x bliver konverteret til double,
da 12.223 er en double.
>
> if ( (float)x == (char)11 )
11 bliver konverteret til float.
>
> if ( (float)x != (long)1251515L )
1251515 bliver konverteret til float.
>

Det bedste er vist at tage fat i C standarden, denne
kan købes hos www.ansi.org, eller man kan downloade
den sidste draft til den nuværende standard her:

http://anubis.dkuug.dk/jtc1/sc22/open/n2794/n2794.pdf

Og kikke i de relevante afsnit, jeg tror det er

"6.3.1.8 Usual arithmetic conversions"

/b


Kasper Larsen (23-02-2004)
Kommentar
Fra : Kasper Larsen


Dato : 23-02-04 16:59


"Lasse Madsen" <Lasse.madsen@elektronik.dk> skrev i en meddelelse
news:c1bbte$1flb$1@news.cybercity.dk...
> Findes der nogle regler i C om håndtering af floats i IF sætninger og
> sammenligninger mod andre data typer feks char's int's long's etc. ?
>
> if ( (float)x > 12.223 )
>
> if ( (float)x == (char)11 )
>
> if ( (float)x != (long)1251515L )
>
> osv...

Jeg skal gerne indrømme at jeg ikke er nogen ørn til at kode, men lige netop
dette problem har jeg slået mig på så tit at jeg efterhånden har lært at
undgå det <g>

if( (float)x == double(y)) dur ikke ( så vidt jeg kan se ) da operator ==
ikke "virker" på decimaltal, jeg bruger i stedet denne :

if( fabs( x -y) < MINDIFF) // MINDIFF er feks. defineret til 0.01

Kasper



Bertel Brander (23-02-2004)
Kommentar
Fra : Bertel Brander


Dato : 23-02-04 20:32

Kasper Larsen wrote:
> "Lasse Madsen" <Lasse.madsen@elektronik.dk> skrev i en meddelelse
> news:c1bbte$1flb$1@news.cybercity.dk...
>
>>Findes der nogle regler i C om håndtering af floats i IF sætninger og
>>sammenligninger mod andre data typer feks char's int's long's etc. ?
>>
>>if ( (float)x > 12.223 )
>>
>>if ( (float)x == (char)11 )
>>
>>if ( (float)x != (long)1251515L )
>>
>>osv...
>
>
> Jeg skal gerne indrømme at jeg ikke er nogen ørn til at kode, men lige netop
> dette problem har jeg slået mig på så tit at jeg efterhånden har lært at
> undgå det <g>
>
> if( (float)x == double(y)) dur ikke ( så vidt jeg kan se ) da operator ==
> ikke "virker" på decimaltal, jeg bruger i stedet denne :
>
> if( fabs( x -y) < MINDIFF) // MINDIFF er feks. defineret til 0.01
>

Man kan bruge FLT_EPSILON/DBL_EPSILON/LDBL_EPSILON i stedet for MINDIFF,
disse er defineret i float.h

/b


Anders J. Munch (24-02-2004)
Kommentar
Fra : Anders J. Munch


Dato : 24-02-04 11:48

"Bertel Brander" <bertel@post4.tele.dk> wrote:
> >
> > if( fabs( x -y) < MINDIFF) // MINDIFF er feks. defineret til 0.01
> >
>
> Man kan bruge FLT_EPSILON/DBL_EPSILON/LDBL_EPSILON i stedet for MINDIFF,
> disse er defineret i float.h

Nej!

Man kan bruge *_EPSILON som komponent i et udtryk, der finder en
velegnet tolerance, men man kan ikke erstatte MINDIFF direkte med
*_EPSILON.

mvh. Anders



Bertel Brander (24-02-2004)
Kommentar
Fra : Bertel Brander


Dato : 24-02-04 19:46

Anders J. Munch wrote:
> "Bertel Brander" <bertel@post4.tele.dk> wrote:
>
>>>if( fabs( x -y) < MINDIFF) // MINDIFF er feks. defineret til 0.01
>>>
>>
>>Man kan bruge FLT_EPSILON/DBL_EPSILON/LDBL_EPSILON i stedet for MINDIFF,
>>disse er defineret i float.h
>
>
> Nej!
>
> Man kan bruge *_EPSILON som komponent i et udtryk, der finder en
> velegnet tolerance, men man kan ikke erstatte MINDIFF direkte med
> *_EPSILON.
>

Du har ganske ret. Jeg har programeret i C (og C++) i > 10 år, men
har (stort set) aldrig haft brug for floating point. Jeg skal for
fremtiden afholde mig fra at udtale mig om disse.

Ved du (eller nogen anden) hvordan man laver et udtryk baseret på
*_EPSILON der kan bruges i stedet for MINDIFF?

/b


Anders J. Munch (25-02-2004)
Kommentar
Fra : Anders J. Munch


Dato : 25-02-04 10:02

"Bertel Brander" <bertel@post4.tele.dk> wrote:
>
> Ved du (eller nogen anden) hvordan man laver et udtryk baseret på
> *_EPSILON der kan bruges i stedet for MINDIFF?

Et skud fra hoften:

(1 << K) * EPSILON * max(fabs(x),fabs(y))

hvor K er antal bits man ikke har tillid til, udfra en konkret
vurdering af de beregninger der ligger til grund for x og y.

Ikke at det er noget jeg selv bruger. Når man endeligt en sjælden gang
vil sammenligne FP tal for lighed, ligger der jo et konkret formål
bag, og udfra det formål kan man typisk sætte en tolerance, som er
meget større.

Eller mindre: Et sted hvor direkte float-sammenligning kan være
nyttigt er i caching; der er man ikke bange for falske negative. Så
jeg erstatter gladeligt:

f_x = f(x);

med

static double forrige_f_x, forrige_x = VÆRDI_SOM_x_IKKE_KAN_ANTAGE;
if(x != forrige_x)
forrige_f_x = f(x);
f_x = forrige_f_x;

alt imens jeg mumler noget i skægget om at hvis Kahans algoritmiske
forståelse havde været på højde med hans numeriske forståelse, så
ville det også have virket for IEEE NaN.

mvh. Anders



Thomas Krog (25-02-2004)
Kommentar
Fra : Thomas Krog


Dato : 25-02-04 10:42

> static double forrige_f_x, forrige_x = VÆRDI_SOM_x_IKKE_KAN_ANTAGE;
> if(x != forrige_x)
> forrige_f_x = f(x);
> f_x = forrige_f_x;

hvis x kan antage alle værdier kunne man gøre sådan:

static double forrige_x = 0.0f;
static double forrige_f_x = f(forrige_x);
if(x != forrige_x)
forrige_f_x = f(x);
f_x = forrige_f_x;

dvs. f(x) bliver kørt en gang mere end i din løsning (hvilket næppe har
betydning i praksis)



Lasse Madsen (23-02-2004)
Kommentar
Fra : Lasse Madsen


Dato : 23-02-04 22:59

Hej Kasper

> if( (float)x == double(y)) dur ikke ( så vidt jeg kan se ) da operator ==
> ikke "virker" på decimaltal, jeg bruger i stedet denne :

det har vel ingen betyning hvis:

float x;
double y;
x = 12;
y = 12;

if ( x == y ) ....

dette burde vel altid virke så længe x ikke optræder som et komma tal ?

> if( fabs( x -y) < MINDIFF) // MINDIFF er feks. defineret til 0.01

Er dette den korrekte måde ? burde enhver compiler ikke kunne "regne ud"
hvad det er du forsøger at gøre og derved vide at den skal typecase noget i
stil med

if ( x == (float)y ) ... så nu skal det da virke !!!???

P.s. compileren er CVAVR på en Embedded 8bit platform ...

m.v.h.
Lasse Madsen



Bertel Brander (23-02-2004)
Kommentar
Fra : Bertel Brander


Dato : 23-02-04 23:39

Lasse Madsen wrote:

> Hej Kasper
>
>
>>if( (float)x == double(y)) dur ikke ( så vidt jeg kan se ) da operator ==
>>ikke "virker" på decimaltal, jeg bruger i stedet denne :
>
>
> det har vel ingen betyning hvis:
>
> float x;
> double y;
> x = 12;
> y = 12;
>
> if ( x == y ) ....
>
> dette burde vel altid virke så længe x ikke optræder som et komma tal ?

Med "små" ikke kommatal bør det virke, men så ville det vel være mere
optimalt at bruge int/long.

>
>
>>if( fabs( x -y) < MINDIFF) // MINDIFF er feks. defineret til 0.01
>
>
> Er dette den korrekte måde ?

Ja, se f.ex:
http://www.eskimo.com/~scs/C-faq/q14.5.html

/b


Igor V. Rafienko (23-02-2004)
Kommentar
Fra : Igor V. Rafienko


Dato : 23-02-04 23:40

[ Lasse Madsen ]


[ ... ]

> det har vel ingen betyning hvis:
>
> float x;
> double y;
> x = 12;
> y = 12;
>
> if ( x == y ) ....


Er du sikker på det:

$ cat floats.c
#include <limits.h>

int
main( int argc, char *argv[] )
{
float x = INT_MAX - 10;
double y = INT_MAX - 12 + 2.0;

if ( x == y )
puts( "equal\n" );
else
puts( "unequal?\n" );
}

$ gcc floats.c && ./a.out
unequal?
$

(hint: FLT_DIG)


> dette burde vel altid virke så længe x ikke optræder som et komma
> tal ?


Nei, hvilket eksempelet mitt forhåpentligvis illustrerer. Flyttall er
ganske ekle, sånn sett.

[ ... ]





ivr
--
<html><form><input type crash></form></html>

Jesper Louis Anderse~ (24-02-2004)
Kommentar
Fra : Jesper Louis Anderse~


Dato : 24-02-04 16:49

In article <xjvwu6dto6r.fsf@viisi.ifi.uio.no>, Igor V. Rafienko wrote:

> (hint: FLT_DIG)

Ah, ja. Floating point numbers IEEE style er fede at have med og goere.
De er diskrete og sammenligning af dem kan hurtigt blive sjov. Man
kan iovrigt diskutere om == operatoren giver mening som aekvivalens-
relation over IEEE floating points. Specielt har du nemlig at
NaN != NaN, men aekvivalensrelationer er som bekendt refleksive
(x == x).

Mit yndlingssprog har valgt at floating point numbers ikke kan sammen-
lignes via den gaengse ''=='' operator. Der findes dog stadigt
sammenligning, IEEE-style.

--
j.

Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408921
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste