Strona 1 z 2

[C] Prosty kalkulator liczb rzeczywistych

: 27 lip 2011, o 10:27
autor: M Franek52525
Proszę o pomoc w zrozumieniu dlaczego ten program wyświetla ciągle zły wynik:

Kod: Zaznacz cały

#include<stdio.h>
int main()
{
    signed long x,y,z;
    printf("Podaj x:
");
    scanf("%f",&x);
    printf("Podaj y:
");
    scanf("%f",&y);
    z=x+y;
    printf("x+y=%g
",z);
    return 0;
} 

[C] Prosty kalkulator liczb rzeczywistych

: 27 lip 2011, o 11:38
autor: thenighthawk4
Spójrz:

Kod: Zaznacz cały

signed long x,y,z;
i porównaj z tym:

Kod: Zaznacz cały

scanf("%f",&x);
oraz z tym:

Kod: Zaznacz cały

printf("x+y=%g
",z);
Zastanów się, co widzisz dziwnego?
Co robi parametr %f i %g?

[C] Prosty kalkulator liczb rzeczywistych

: 27 lip 2011, o 11:59
autor: M Franek52525
%f i%g w funkcji scanf służy do odczytu liczb rzeczywistych.
W printf nie ma takiego formatu. Czy o to chodzi?

[C] Prosty kalkulator liczb rzeczywistych

: 27 lip 2011, o 12:03
autor: thenighthawk4
Jakiego typu zmienne zadeklarowałeś? Czy przeznaczone dla liczb rzeczywistych?

[C] Prosty kalkulator liczb rzeczywistych

: 27 lip 2011, o 12:08
autor: M Franek52525
Aha faktycznie nie doczytałem, że to do liczb całkowitych
Zmieniłem na float i działa, tylko nie mogę wymyślić co z long double?

[C] Prosty kalkulator liczb rzeczywistych

: 27 lip 2011, o 13:07
autor: Afish
Specifies a size different from int (in the case of d, i and n), unsigned int (in the case of o, u and x) or float (in the case of e, f and g) for the data pointed by the corresponding additional argument:
h : short int (for d, i and n), or unsigned short int (for o, u and x)
l : long int (for d, i and n), or unsigned long int (for o, u and x), or double (for e, f and g)
L : long double (for e, f and g)

[C] Prosty kalkulator liczb rzeczywistych

: 29 lip 2011, o 11:29
autor: M Franek52525
Nie wiem jak mam mam wpisać te specyfikatory rozmiaru żeby to działało.

[C] Prosty kalkulator liczb rzeczywistych

: 29 lip 2011, o 15:08
autor: thenighthawk4
Mógłbyś napisać jak próbowałeś to zrobić?
Co nie działa? Pokaż kod po modyfikacjach, pokaż przykładowe wejście i wyjście.
Jakiego kompilatora używasz?

Napisałem tak:

Kod: Zaznacz cały

#include <stdio.h>

int main()
{
	long double x,y,z;
	printf("Podaj x:
");
	scanf("%Lf",&x);
	printf("Podaj y:
");
	scanf("%Lf",&y);
	z=x+y;
	printf("x+y=%Lf
", z);
	
	return 0;
}
Na Linuksie działa bezproblemowo, jednak na Windowsie (MinGW) printf wypisuje za każdym razem -2.
Z tego, co wyczytałem, MinGW sprawia problemy przy połączeniu long double z printf i scanf



W ogóle po co Ci tak wielkie liczby?

[C] Prosty kalkulator liczb rzeczywistych

: 29 lip 2011, o 21:41
autor: M Franek52525
Ja używam programu code blocks.
Próbowałem tak:

Kod: Zaznacz cały

#include<stdio.h>
int main()
{
    long double x,y,z;
    printf("Podaj x:
");
    scanf("%Lg",&x);
    printf("Podaj y:
");
    scanf("%Lg",&y);
    z=x+y;
    printf("x+y=%Lg
",z);
    return 0;
}
Efektem tego jest wynik=-2.
Po prostu chce zrobić ten kalkulator na tak dużych liczbach, żeby się w końcu czegoś nauczyć.
Pomimo, że będzie można wykonać tylko jedną operację naraz.

[C] Prosty kalkulator liczb rzeczywistych

: 1 sie 2011, o 23:58
autor: thenighthawk4
Code::Blocks to środowisko programistyczne.
Upewnij się jakiego kompilatora używasz.
Jeśli twój system to Windows, prawdopodobnie korzystasz z GCC dostarczanego przez MinGW.

Na temat problemów z MinGW podałem już linka. Nie wiem, czy można je obejść przy zachowaniu pełnej funkcjonalności typu long double. Ostatecznie możesz użyć innego kompilatora, który wspierałby w pełni ten typ lub wyemigrować na Pingwina

Ilu miejsc po przecinku potrzebujesz? Może wystarczy odpowiednio sformatować wyjście
(patrz printf na

Kod: Zaznacz cały

http://cplusplus.com/reference/
).

Sprawdziłem działanie long double w środowisku Code::Blocks na kompilatorze LCC.
Program oblicza wartość \(\displaystyle{ \sqrt{2}}\) za pomocą funkcji z math.h, oraz implementacji metody Newtona-Raphsona (nie napisałem jej za dobrze) dla typów double i long double.

Kod: Zaznacz cały

#include <stdio.h>
#include <math.h>

long double PierwiastekL(long double &val, unsigned int n);
double Pierwiastek(double &val, unsigned int n);

int main()
{
    long double lox, loz;
    double x, z;

    printf("Podaj lox:
");
    scanf("%Lf",&lox);

    printf("Podaj x:
");
    scanf("%lf",&x);

    loz = sqrt(lox);
    printf("loz=%.25Lf
", loz);
    loz = PierwiastekL(lox, 2);
    printf("loz=%.25Lf
", loz);

    z = sqrt(x);
    printf("  z=%.25lf
", z);
    z = Pierwiastek(x , 2);
    printf("  z=%.25lf
", z);

    return 0;
}

long double PierwiastekL(long double &val, unsigned int n)
{
    const long double d = 0.00000000000000001;
    long double a = 1;

    while( fabs(val - pow(a, n)) > d )
        a = ( val/pow(a, n-1) + (n-1)*a ) / n;

    return a;
}

double Pierwiastek(double &val, unsigned int n)
{
    const double d = 0.000000000000001;
    double a = 1;

    while( fabs(val - pow(a, n)) > d )
        a = ( val/pow(a, n-1) + (n-1)*a ) / n;

    return a;
}
Zmienne lokalne d mają maksymalną ilość miejsc po przecinku, która nie sprawiała u mnie problemów.

Rezultat sam oceń:

Kod: Zaznacz cały

loz=1.4142135623730950490000000
loz=1.4142135623730950490000000
  z=1.4142135623730950000000000
  z=1.4142135623730950000000000

[C] Prosty kalkulator liczb rzeczywistych

: 7 sie 2011, o 15:44
autor: M Franek52525
U mnie nie chce działać

[C] Prosty kalkulator liczb rzeczywistych

: 7 sie 2011, o 21:01
autor: void_t
Nie chce działać z jakiego powodu? Nie kompiluje sie?

[C] Prosty kalkulator liczb rzeczywistych

: 8 sie 2011, o 14:37
autor: M Franek52525
Tak, nie chce się skompilować

[C] Prosty kalkulator liczb rzeczywistych

: 8 sie 2011, o 14:42
autor: void_t
Nic dziwnego. thenighthawk4 najprawdopodobniej omyłkowo zastosował 2, wykluczające się w tym aspekcie składnie - C i C++.

Kod: Zaznacz cały

long double PierwiastekL(long double &val, unsigned int n);
double Pierwiastek(double &val, unsigned int n);
Powinno być (dla C):

Kod: Zaznacz cały

long double PierwiastekL(long double *val, unsigned int n);
double Pierwiastek(double *val, unsigned int n);
A co za tym idzie:

Kod: Zaznacz cały

loz = PierwiastekL(lox, 2);
Na

Kod: Zaznacz cały

loz = PierwiastekL(&lox, 2);

Kod: Zaznacz cały

loz = PierwiastekL(lox, 2);
Na

Kod: Zaznacz cały

loz = PierwiastekL(&lox, 2);
Oraz w kodzie typu

Kod: Zaznacz cały

 while( fabs(val - pow(a, n)) > d )
        a = ( val/pow(a, n-1) + (n-1)*a ) / n;
Zamienić należy 'val' na *val, jako że odwołujemy się do wartości tego na co wskazuje pointer, a nie do adresu tego czegoś.

Ponadto w funkcji PierwiastekL funkcje fabs i pow powinny zostać zamienione na fabsl oraz powl, bowiem operujemy na typie long double a nie double

[C] Prosty kalkulator liczb rzeczywistych

: 8 sie 2011, o 16:53
autor: thenighthawk4
void_t, rzeczywiście pomieszałem C z C++, jednak zastanawiam się, dlaczego u mnie się to skompilowało zarówno w GCC, jak i w LCC.

Co do pow i fabs, nie ma to jak kopiowanie kodu
Poprawiłem według Twoich zaleceń, jednak wyjście nie uległo zmianie, precyzja pozostaje ta sama.

Nie wiem, czy może źle zrobiłem coś przy ograniczeniu zmienną d, czy typ argumentu (double/long double) nie ma tutaj znaczenia?
Sądząc po tym: funkcja sqrt jest rzutowana na odpowiedni typ, a wydaje mi się, że 2-3 miejsca po przecinku, to stosunkowo mało jak na 2 dodatkowe bajty. Próbowałem też z sqrtl.
O co może tu chodzić?