Машинный ноль | это... Что такое Машинный ноль? (original) (raw)

Question book-2.svg Эта статья нуждается в дополнительных источниках для улучшения проверяемости. Вы можете помочь улучшить эту статью, добавив ссылки на авторитетные источники.Не подтверждённая источниками информация может быть поставлена под сомнение и удалена.

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

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

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

При представлении чисел со знаком в обратных двоичных кодах существуют проблема[_уточнить_] наличия двух обратных кодов числа 0: «положительный нуль» и «отрицательный нуль».

Пример

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

#include <stdio.h> int main() { float e,e1; /* e1 - вспомогательная переменная / int k=0; / k - счетчик итераций */ e=1.0; do { e=e/2.0; e1=e+1.0; k++; } while (e1>1.0); printf("Число делений на 2: %d\n",k); printf("Машинный эпсилон: %e\n",e); return 0; }

Пример на языке C++.

#include #include <stdint.h> #include

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.