|
| Mærkelig double-værdi Fra : Thomas Arildsen |
Dato : 17-12-01 09:35 |
|
Hvad i alverden skal det sige, når en double-variabel har
ærdien -1.#IND000000000?
Mvh. Thomas Arildsen
| |
Thomas Arildsen (17-12-2001)
| Kommentar Fra : Thomas Arildsen |
Dato : 17-12-01 11:20 |
|
"Thomas Arildsen" <tari00@kom.auc.dk> skrev i en meddelelse
news:9vkani$el6$1@sunsite.dk...
> Hvad i alverden skal det sige, når en double-variabel har
> værdien -1.#IND000000000?
Nå, så fandt jeg ud af det. Det er åbenbart noget der sker ved division med
0. Jeg havde ellers forventet at sådan noget gav en runtime-error, men
åbenbart ikke.
Mvh. Thomas Arildsen
| |
Ivan Johansen (17-12-2001)
| Kommentar Fra : Ivan Johansen |
Dato : 17-12-01 11:34 |
|
Thomas Arildsen wrote:
> "Thomas Arildsen" <tari00@kom.auc.dk> skrev i en meddelelse
> news:9vkani$el6$1@sunsite.dk...
>
>>Hvad i alverden skal det sige, når en double-variabel har
>>værdien -1.#IND000000000?
>>
>
> Nå, så fandt jeg ud af det. Det er åbenbart noget der sker ved division med
> 0. Jeg havde ellers forventet at sådan noget gav en runtime-error, men
> åbenbart ikke.
Division med 0 er udefineret. Compileren bestemmer selv hvad den gør.
Borlands compiler smider en exception. For at være kompatibel, bør du
sørge for at der aldrig kan blive divideret med 0.
Ivan Johansen
| |
Kent Friis (17-12-2001)
| Kommentar Fra : Kent Friis |
Dato : 17-12-01 16:35 |
|
Den Mon, 17 Dec 2001 11:33:52 +0100 skrev Ivan Johansen:
>Thomas Arildsen wrote:
>
>> "Thomas Arildsen" <tari00@kom.auc.dk> skrev i en meddelelse
>> news:9vkani$el6$1@sunsite.dk...
>>
>>>Hvad i alverden skal det sige, når en double-variabel har
>>>værdien -1.#IND000000000?
>>>
>>
>> Nå, så fandt jeg ud af det. Det er åbenbart noget der sker ved division med
>> 0. Jeg havde ellers forventet at sådan noget gav en runtime-error, men
>> åbenbart ikke.
>
>Division med 0 er udefineret. Compileren bestemmer selv hvad den gør.
>Borlands compiler smider en exception. For at være kompatibel, bør du
>sørge for at der aldrig kan blive divideret med 0.
GCC giver INF (infinity), og hvis man fx. tager arctan(INF), så får
man også det korrekte resultat (90 grader). Det er meget smart, når
man sidder med nogle vektor-beregninger, som nogengange giver nogle
vinkler hvor beregningen kræver division med 0.
Mvh
Kent
--
http://www.celebrityshine.com/~kfr/
| |
Jonas Meyer Rasmusse~ (17-12-2001)
| Kommentar Fra : Jonas Meyer Rasmusse~ |
Dato : 17-12-01 19:26 |
|
kfr@fleggaard.dk (Kent Friis) writes:
> GCC giver INF (infinity), og hvis man fx. tager arctan(INF), så får
> man også det korrekte resultat (90 grader). Det er meget smart, når
> man sidder med nogle vektor-beregninger, som nogengange giver nogle
> vinkler hvor beregningen kræver division med 0.
Men hvad nu hvis det _er_ en fejl, som det velsagtens er 95% af gangene?
Jeg havde problemet for noget tid siden, med noget kode
der dividerede med 0, og pga GCC's "smarte" INF, kunne jeg ikke
finde min fejl, og jeg måtte knokle mig igennem koden linie for linie,
fordi jeg ikke kunne finde en metode til at få undtagelser istedet for
INF...
Kan det lade sig gøre?
Jonas Meyer Rasmussen
| |
Byrial Jensen (17-12-2001)
| Kommentar Fra : Byrial Jensen |
Dato : 17-12-01 22:09 |
|
Jonas Meyer Rasmussen <meyer@fafner.diku.dk> skrev:
> kfr@fleggaard.dk (Kent Friis) writes:
>
>> GCC giver INF (infinity), og hvis man fx. tager arctan(INF), så får
>> man også det korrekte resultat (90 grader). Det er meget smart, når
>> man sidder med nogle vektor-beregninger, som nogengange giver nogle
>> vinkler hvor beregningen kræver division med 0.
>
> Men hvad nu hvis det _er_ en fejl, som det velsagtens er 95% af gangene?
> Jeg havde problemet for noget tid siden, med noget kode
> der dividerede med 0, og pga GCC's "smarte" INF, kunne jeg ikke
> finde min fejl, og jeg måtte knokle mig igennem koden linie for linie,
> fordi jeg ikke kunne finde en metode til at få undtagelser istedet for
> INF...
> Kan det lade sig gøre?
Det kan det godt, men det styres ikke af gcc, men af ens libc.
Nedenstående program illustrerer brug af FE_DIVBYZERO-flaget.
Tilsvarende det findes også FE_INEXACT, FE_UNDERFLOW, FE_OVERFLOW
og FE_INVALID. Disse flag i specificeret i C99, men det er
implementations- og hardware-afhængigt i hvilken grad de er
understøttet.
De 2 første fe*-funktioner er standard (C99), mens den sidste er en
GNU-udvidelse.
NB. Det følgende er et C-program. Jeg har ingen ide om hvorvidt det
virker i C++.
$ cat div.c
#include <stdio.h>
#include <fenv.h>
float del (float a, float b)
{
return a / b;
}
int main ()
{
int rc;
int raised;
/* Slet alle fejlflag i FP-status. (C99) */
rc = feclearexcept (FE_ALL_EXCEPT);
if (rc) { perror("clearexcept"); return 1; }
printf ("5.0/0.0 = %f\n", del (5.0, 0.0));
/* Test om der er sket en division med nul. (C99) */
raised = fetestexcept (FE_DIVBYZERO);
if (raised & FE_DIVBYZERO)
{
printf ("Ups. Der er sket en division med nul.\n");
}
/* Lav en SIGFPE ved division med nul. (GNU-udvidelse) */
rc = feenableexcept (FE_DIVBYZERO);
if (rc) { perror("enableexcept"); return 1; }
printf ("6.0/0.0 = %f\n", del (6.0, 0.0));
return 0;
}
$ gcc div.c -lm -o div
$ ./div
5.0/0.0 = inf
Ups. Der er sket en division med nul.
Undtagelsestilfælde ved flydendetals-operation (core dumped)
$
| |
Byrial Jensen (17-12-2001)
| Kommentar Fra : Byrial Jensen |
Dato : 17-12-01 22:31 |
|
Byrial Jensen <bjensen@nospam.dk> skrev:
> /* Lav en SIGFPE ved division med nul. (GNU-udvidelse) */
> rc = feenableexcept (FE_DIVBYZERO);
Lige en korrektion. Der mangler et kald af feclearexcept() til at
slette den FP-statuskode som den første division med 0 gav, før
dette kald af feenableexcept(). Ellers vil funktionen smide core
umiddelbart i stedet for at returnere.
| |
|
|