Машинный ноль

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск
Представление машинного нуля в числах с плавающей запятой при двузначном порядке

Машинный ноль (Машинный нуль) — числовое значение с таким отрицательным порядком, которое воспринимаемое машиной как ноль.

Машинный эпсилон (англ. Machine epsilon) — числовое значение, меньше которого невозможно задавать точность для любого алгоритма, возвращающего вещественные числа. Абсолютное значение «машинного эпсилон» зависит от разрядности сетки применяемой ЭВМ, от принятой в конкретном трансляторе точности представления вещественных чисел и от значений, используемых для оценки точности.[1]

В языке Си существуют предельные константы FLT_EPSILON и DBL_EPSILON называемые «машинными эпсилон» относительно вещественного значения 1.0. FLT_EPSILON — максимальное значение типа float и имеет значение 1.2E-7, DBL_EPSILON — максимальное значение типа double и имеет значение 2.2E-16. Сумма каждого из этих значений со значением 1.0 не отличается от 1.0.

Проблема машинного эпсилон в том, что два числа считаются одинаковыми, если они отличаются на величину, меньшую по модулю, чем машинный эпсилон.[источник не указан 1741 день]

Пример[править | править вики-текст]

Пример вычисления машинного эпсилона (не путать с машинным нулём) на языке Си.

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)

См. также[править | править вики-текст]

Примечания[править | править вики-текст]

  1. Подбельский В. В., Фомин С. С. Программирование по на языке Си: Учеб.пособие. Москва: Изд-во Финансы и статистика, 2003.