Sprawdzanie dziedziny funkcji operującej na double

0

Mam taki kod w C:

for(x = -5.0 ; x <= 10.0 ; x += 0.2)
{
    //...
    if(x >= 0.0 && (pow(x, 2.0) - sqrt(x)) > 0.0)
    {
        double suma = pow(log(pow(x, 2.0) - sqrt(x))/log(5), 1/3.0);
        printf("%f ", suma);
    }
    //...
}

Dlaczego pomimo sprawdzenia niezbędnych warunków dla dziedziny funkcji, wywala mi on błędy dziedziny przy x = 1.0 (tu akurat drugi warunek przechodzi, pomimo, że liczba logarytmowana jest równa dokładnie 0.0), 1.2 i 1.3?

0

Nie wywala błędów, wykonuje się dla if == true zarówno dla 1.0 jak i 1.2, dla 1.3 nie sprawdzasz.

0

Z 1.3 się pomyliłem, miało być 1.4:

//OUTPUT:
//...
x=0.400000	
x=0.600000	
x=0.800000	
x=1.000000	-nan //tutaj zaczynaja sie problemy, if powinien byc == false
x=1.200000	-nan //a tutaj 
x=1.400000	-nan //i tutaj nie wiem dlaczego jest ten blad dziedziny
x=1.600000	0.543634
x=1.800000	0.735742
x=2.000000	0.838856
x=2.200000	0.909537
//...
0

Twój x jest na pewno typu float? Dla 1.2 oraz 1.4 if == true.

0

OK, pow nie działa dla ujemnego x i niecałkowitego y, musiałem napisać swoją funkcję wrapper - http://stackoverflow.com/questions/4269069/finding-cube-root-in-c/4269119.

Niemniej jednak mam pytanie odnośnie tego double x = 1.0 (bo pętla z pierwszego postu do niego dochodzi poprzez dodawanie 0.2).

Dlaczego przy x = 1.0:

(pow(x, 2.0) - sqrt(x)) > 0.0

powyższy warunek jest spełniony, ponieważ jak sprawdziłem, to wyrażenie jest równe liczbie 0.00000000000000310862... (wyswietlalem wczesniej za malo miejsc po przecinku przy %f). 1*1-pierw(1) to ewidentnie 0.0, tak więc co - dodawanie 0.2 nawet przy double grozi utratą jakiejś precyzji?

Z tą utratą precyzji (jesli ona tutaj jest błędem) spotykam sie od dłuzszego czasu - czy znacie moze jakis link do artykułu który tłumaczy to intuicyjnie na necie, bo jest to dla mnie dalej nie jasne, ze nawet nie mogę inkrementować double co 0.2.

0
if(x >= 0.0 && (pow(x, 2.0) - sqrt(x)) > 1.0)
0

No ok, dla x=1.0 bedzie poprawnie czyli if == false, ale if mi wtedy odhaczy 1.2 i 1.4 - a po podstawieniu do wzoru z pierwszego postu takich x'ów chyba nie będzie naruszenia dziedziny funkcji, którą tam obliczam (to całe wyrazenie pod szesciennym pierwiastkiem) - w rezultacie stracę te dwa wyniki dla x = 1.2 i 1.4?

0

Powiedz mi ile bpędzie (-0.159)0.3333 ?

0

Kalkulator mówi, że będzie tyle: −0,541750151, ale co to ma do rzeczy?

0

mylisz: (-0.159)0.3333 z: -(0.1590.3333)

0

Przecież to to samo, pierwiastek nieparzystego stopnia zachowuje znak wyrazenia pod pierwiastkiem.

0

Nie jest to samo, ponieważ 0.3333 != 1/3 zaś w C/C++ nie istnieje 1/3: http://ideone.com/OGKF4d

0

OK, ale dalej mam mętlik - dlaczego dałeś > 1.0 w swoim pierwszym poście jako warunek do liczby logarytmowanej?

0

Człowieku wróć do podstawówki. Masz dopilnować aby: Log5(cos)>0

0

W jaki sposób z mojego pierwotnego wyrażenia nagle wziął Ci się jakiś cosinus i warunek, że ten cały logarytm ma być większy od 0?

0

No chyba, że zamiast cos miało być coś. A logarytm > 0 ? Przeciez pod pierwiastkiem nieparzystego stopnia moze stac liczba ujemna.

0

Czyli z pierwiastka sześciennego robi się kwadratowy? I log5 co**ś** > 0 --> log5 co**ś** > log5 1 ?

0
first-timer napisał(a):

Dlaczego przy x = 1.0:

(pow(x, 2.0) - sqrt(x)) > 0.0

powyższy warunek jest spełniony, ponieważ jak sprawdziłem, to wyrażenie jest równe liczbie 0.00000000000000310862...

jakiegoś szajsu chyba używasz.

Funkcja pow na pewno daje dokładny wynik 1 dla 1 do x <> 0, i sqrt tak samo.

można od biedy użyć:

abs(pow(x, 2.0) - sqrt(x)) > eps

gdzie eps to precyzja double, chyba 2-53 =~ 1e-16

0
  1. W języku C/C++ nie da się zrobić stricte pierwiastka sześciennego.
  2. log5(coś)>0 --> coś>1
1
_13th_Dragon napisał(a):

W języku C/C++ nie da się zrobić stricte pierwiastka sześciennego.

log5(coś)>0 --> coś>1

Jak to nie da się?
http://en.cppreference.com/w/c/numeric/math/cbrt

1 użytkowników online, w tym zalogowanych: 0, gości: 1