C/exp

< C
(Przekierowano z C/expm1)

Plik nagłówkowy

edytuj

math.h

double      exp   (double      x);
float       expf  (float       x);
long double expl  (long double x);

double      exp2  (double      x);
float       exp2f (float       x);
long double exp2l (long double x);

double      expm1 (double      x);
float       expm1f(float       x);
long double expm1l(long double x);

double      ldexp (double      x, int n);
float       ldexpf(float       x, int n);
long double ldexpl(long double x, int n);

double      scalbn (double      x, int n);
float       scalbnf(float       x, int n);
long double scalbnl(long double x, int n);

double      scalbln (double      x, long n);
float       scalblnf(float       x, long n);
long double scalblnl(long double x, long n);
double      log (double      x);
float       logf(float       x);
long double logl(long double x);

double      log10 (double      x);
float       log10f(float       x);
long double log10l(long double x);

double      log1p (double      x);
float       log1pf(float       x);
long double log1pl(long double x);

double      log2 (double      x);
float       log2f(float       x);
long double log2l(long double x);

double      logb (double      x);
float       logbf(float       x);
long double logbl(long double x);

int         ilogb (double      x);
int         ilogbf(float       x);
int         ilogbl(long double x);

double      frexp (double      x, int *n);
float       frexpf(float       x, int *n);
long double frexpl(long double x, int *n);

Stałe

edytuj
#define FP_ILOGB0 watość
#define FP_ILOGBNAN wartość

Argumenty

edytuj
x
argument funkcji
n
wykładnik

Funkcje z przyrostkami "f" i "l" to inne wersje odpowiedniej funkcji bez przyrostka operujące na innych typach danych. Z tego powodu w poniższym opisie odwołanie do konkretnej funkcji będzie oznaczać odwołanie się do wszystkich 3 wersji.

Funkcje obliczają następujące wartości:

exp eksponenta x   czyli  
exp2 dwa do potęgi x  
expm1 eksponenta x pomniejszona o jeden  
ldexp x razy dwa do potęgi n  
scalbln i scalbn x razy FLT_RADIX do potęgi n  
log logarytm naturalny z x   lub  
log10 logarytm dziesiętny z x  
log1p logarytm naturalny z jeden plus x  
log2 logarytm o podstawie dwa z x  
logb zwraca wykładnik podanego argumentu jako liczbę całkowitą ze znakiem, w taki sposób, że dla dodatniego skończonego argumentu zachodzi:  
ilogb jeżeli x jest równy zero wartość FP_ILOGB0; jeżeli jest równy nieskończoność - INT_MAX; jeżeli jest to wartość NaN - FP_ILOGBNAN; w przeciwnym wypadku wartość zwracana przez logb zrzutowaną do typu int
frexp zwraca znormalizowaną część liczby x z przedziału [0,5; 1), a zmiennej wskazywanej przez n zapisuje wykładnik potęgi dwójki; jeżeli x jest równe zero obie części są równe zero

Jeżeli x jest liczbą ujemną (mniejszą od -1) funkcje log, log10 i log2 ustawiają (funkcja log1p ustawia) zmienną errno na EDOM.

Stała FP_ILOGB ma wartość INT_MIN lub -INT_MAX, natomiast FP_ILOGBNAN wartość INT_MAX lub INT_MIN.

Wartość zwracana

edytuj

Wartości odpowiednich funkcji zgodnei z opisem powyżej.

Ponadto, jeżeli wystąpi nadmair funkcja zwraca w wyniku HUGE_VAL z odpowiednim znakiem i ustawia wartość zmeinnej errno na ERANGE. Jeśli wystąpi niedomiar funkcja w wyniku zwraca zero, a to czy do zmiennej errno zostanie zapisana wartość ERANGE zależy od implementacji.

Przykład użycia

edytuj

Bezpieczne użycie

edytuj

Sprawdzanie zakresu zmiennej wejściowej przed użyciem funkcji :

double x, r;

if (isnan(x) || islessequal(x, 0))

{ /* Deal with NaN / pole error / domain error */ }

r = log(x);


Czas rozpadu

edytuj

Czas połowicznego rozpadu pierwiastka to czas, po którym rozpadnie się połowa atomów pierwiastka promieniotwórczego. Poniższy program oblicza liczbę atomów pozostałych po podanym czasie zgodnie ze wzorem:

 

gdzie   to początkowa liczba cząstek a   to czas połowicznego rozpadu.

#include <math.h>
#include <stdio.h>
 
int main()
{
    double N0, T12, t, N;

#if __STDC_VERSION__ < 199901L
    // jesli uzywamy standardu C99
    double lambda;    
#endif
 
    printf("N_0 = ");
    if (scanf("%lf", &N0) != 1) return 1;
 
    printf("T_{1/2} = ");
    if (scanf("%lf", &T12) != 1) return 1;
 
    printf("t = ");
    if (scanf("%lf", &t) != 1) return 1;
 
#if __STDC_VERSION__ < 199901L
    // jesli uzywamy standardu C99
    lambda = log(2) / T12;
    N = N0 * exp(-lambda * t);
#else
    N = N0 * exp2(-t / T12);
#endif
 
    printf("N = %g\n", N);
    return 0;
}


/*


 gcc i.c -Wall -Wextra -lm

 https://stackoverflow.com/questions/108318/how-can-i-test-whether-a-number-is-a-power-of-2
 (n>0 && ((n & (n-1)) == 0))

 https://stackoverflow.com/questions/160930/how-do-i-check-if-an-integer-is-even-or-odd
if (x % 2) {  } //  x is odd 
 An integer is even if it is a multiple of two, and odd if it is not.

*/


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

int main(void)
{
	int n = 8;
	if (n % 2) 
		{ fprintf(stdout, "%d is even\n", n);}
		else { fprintf(stdout, "%d is odd\n", n);}
		
	if (n>0 && ((n & (n-1)) == 0))
		{ fprintf(stdout, "%d is power of 2 = 2^%d\n", n, (int) log2(n));}
		else { fprintf(stdout, "%d is not the power of t\n", n);}
	


	return 0;
}

wynik:

8 is odd
8 is power of 2 = 2^3

Wersje funkcji z przyroskiem "f" i "l" (tzn. wersje operujące na zmiennych typu float i long double) zostały wprowadzone dopiero w standardzie C99. Również funkcje exp2, expm1, scalbn, scalbln, log2, log1p, logb oraz ilogb, a także stałe FP_ILOGB0 oraz FP_ILOGBNAN zosatły wprowadzone dopiero w standardzie C99.

W przypadku użycia funkcji matematycznych może zaistnieć konieczność podania odpowiedniego argumentu linkerowi, aby ten połączył program z biblioteką matematyczną. Np. na systemach GNU/Linux jest to -lm.


Źródła

edytuj