Машинный перевод на основе трансформации
- 1 year ago
- 0
- 0
Машинный ноль ( Машинный нуль ) — числовое значение с таким отрицательным порядком, которое воспринимается машиной как ноль .
Машинный эпсилон ( англ. Machine epsilon ) — числовое значение, меньше которого невозможно задавать относительную точность для любого алгоритма, возвращающего вещественные числа . Абсолютное значение «машинного эпсилон» зависит от разрядности сетки применяемой ЭВМ , типа (разрядности) используемых при расчетах чисел, и от принятой в конкретном трансляторе структуры представления вещественных чисел (количества бит, отводимых на мантиссу и на порядок). Формально машинный эпсилон обычно определяют как минимальное из чисел ε, для которого 1+ε>1 при машинных расчетах с числами данного типа . Альтернативное определение — максимальное ε, для которого справедливо равенство 1+ε=1.
Практическая важность машинного эпсилон связана с тем, что два (отличных от нуля) числа являются одинаковыми с точки зрения машинной арифметики, если их относительная разность по модулю меньше (при определении первого типа) или не превосходит (при определении второго типа) машинного эпсилон.
В языке Си существуют предельные константы FLT_EPSILON, DBL_EPSILON и LDBL_EPSILON являющиеся «машинными эпсилон», соответствующими первому определению: FLT_EPSILON = 2 −23 ≈ 1.19e-07 — это машинный эпсилон для чисел типа float (32 бита), DBL_EPSILON = 2 −52 ≈ 2.20e-16 — для типа double (64 бита), и LDBL_EPSILON = 2 −63 ≈ 1.08e-19 — для типа long double (80 бит). При альтернативном определении соответствующие машинные эпсилон будут вдвое меньше: 2 −24 , 2 −53 и 2 −64 .В некоторых компиляторах Си (например gcc, Intel ’s C/C++ compiler) допускается использование переменных четверной точности (_float128, _Quad). Соответствующие машинные эпсилон равны 2 −112 ≈ 1.93e-34 и 2 −113 ≈ 9.63e-35.
Пример вычисления машинного эпсилона (не путать с машинным нулём) на языке Си .
float macheps(void)
{
float e = 1.0f;
while (1.0f + e / 2.0f > 1.0f)
e /= 2.0f;
return e;
}
Пример на языке C++ .
# include <iostream>
# include <stdint.h>
# include <iomanip>
template<typename float_t, typename int_t>
float_t machine_eps()
{
union
{
float_t f;
int_t i;
} one, one_plus, little, last_little;
one.f = 1.0;
little.f = 1.0;
last_little.f = little.f;
while(true)
{
one_plus.f = one.f;
one_plus.f += little.f;
if( one.i != one_plus.i )
{
last_little.f = little.f;
little.f /= 2.0;
}
else
{
return last_little.f;
}
}
}
int main()
{
std::cout << "machine 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;
}
Пример на 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_last
Вывод может быть таким (с использованием IPython ):
In [1]: machineEpsilon(int) Out[1]: 1
In [2]: machineEpsilon(float) Out[2]: 2.2204460492503131e-16
In [3]: machineEpsilon(complex) Out[3]: (2.2204460492503131e-16+0j)