Machine zero ( Machine zero ) este o valoare numerică cu un astfel de exponent negativ, care este percepută de mașină ca zero [1] .
Epsilonul mașinii este o valoare numerică sub care este imposibil să se stabilească precizia relativă pentru orice algoritm care returnează numere reale . Valoarea absolută a „epsilonului mașinii” depinde de lățimea de biți a rețelei utilizate de computer , de tipul (lungimea de biți) utilizată în calculele numerelor și de structura reprezentării numerelor reale adoptată într-un anumit traducător. (numărul de biți alocați pe mantisă și pe ordin). [2] Formal, un epsilon de mașină este de obicei definit ca numărul minim ε pentru care 1+ε>1 în calculele mașinii cu numere de acest tip [3] . O definiție alternativă este ε maxim, pentru care egalitatea 1+ε=1 este adevărată.
Importanța practică a epsilonului mașinii se datorează faptului că două numere (diferite de zero) sunt aceleași din punctul de vedere al aritmeticii mașinii dacă diferența lor relativă în valoare absolută este mai mică (la definirea primului tip) sau nu depășește (la definirea celui de-al doilea tip) mașină epsilon.
Există constante limită în limbajul C FLT_EPSILON, DBL_EPSILON și LDBL_EPSILON care sunt „epsilon de mașină” corespunzătoare primei definiții: FLT_EPSILON = 2 −23 ≈ 1.19e-07 este epsilon de mașină pentru numere flotante (32 de biți), DBL_EPSILON = 2 ≈ 2.20e-16 pentru tipul dublu (64 de biți) și LDBL_EPSILON = 2 −63 ≈ 1.08e-19 pentru tipul dublu lung (80 de biți). Cu o definiție alternativă, epsilonii mașinii corespunzători ar fi jumătate: 2 -24 , 2 -53 și 2 -64 . Unele compilatoare C (de exemplu, gcc, compilatorul Intel C/C++) permit utilizarea variabilelor de precizie quad (_float128 , _Cad). Epsilonii mașinii corespunzători sunt 2 −112 ≈ 1,93e-34 și 2 −113 ≈ 9,63e-35.
Un exemplu de calcul al mașinii epsilon (a nu se confunda cu mașina zero) în limbajul C.
float macheps ( gol ) { float e = 1,0f ; în timp ce ( 1.0f + e / 2.0f > 1.0f ) e /= 2,0f ; returnează e ; }Un exemplu în C++ .
# include <iostream> # include <stdint.h> # include <iomanip> template < typename float_t , typename int_t > float_t machine_eps () { unire { float_t f ; int_t i ; } unu , unu_plus , mic , ultimul_pic ; unul . f = 1,0 ; putin . f = 1,0 ; ultimul_mic . f = putin . f ; în timp ce ( adevărat ) { one_plus . f = unu . f ; one_plus . f += putin . f ; dacă ( unu . i != one_plus . i ) { ultimul_mic . f = putin . f ; putin . f /= 2,0 ; } altfel { return last_little . f ; } } } int main () { std :: cout << "mașină epsilon: \n " ; std :: cout << "float: " << std :: setprecision ( 18 ) << machine_eps < float , uint32_t > () << std :: endl ; std :: cout << "double: " << std :: setprecision ( 18 ) << machine_eps < double , uint64_t > () << std :: endl ; }Exemplu în Python
def machineEpsilon ( func = float ): machine_epsilon = func ( 1 ) while func ( 1 ) + func ( machine_epsilon ) != func ( 1 ): machine_epsilon_last = machine_epsilon machine_epsilon = func ( machine_epsilon ) / func ( 2 ) return machine_epsilon_lastIeșirea ar putea fi așa (folosind IPython ):
În[1]: machineEpsilon(int) Ieșire[1]: 1 În[2]: machineEpsilon(float) Ieșire[2]: 2.2204460492503131e-16 În[3]: mașinăEpsilon(complex) Ieșire[3]: (2.2204460492503131e-16+0j)