какое наибольшее число меньше, чем FLT_EPSILON? - PullRequest
2 голосов
/ 31 января 2012

В C с использованием float.h мне интересно, как мне найти наибольшее число, что, если я добавлю к 1, ответ останется 1.

т.е. 1 + x = 1, как найти x?

Ответы [ 2 ]

8 голосов
/ 31 января 2012

Если вы хотите «наибольшее число, которое меньше, чем FLT_EPSILON»:

x = nextafterf(FLT_EPSILON, 0)

Если вам нужно наибольшее число x такое, что 1.0f + x == 1.0f, то ответ зависит от режима округления, но в режиме округления по умолчанию это просто FLT_EPSILON/2.

Однако все не так просто. Из-за способа округления до ближайшего соседа по соседству даже у вас есть 1.0f + FLT_EPSILON/2 == 1.0f, но:

(1.0f+FLT_EPSILON) + FLT_EPSILON/2 != (1.0f+FLT_EPSILON)

Так что вместо этого вы можете использовать чуть меньшее значение x:

x = nextafterf(FLT_EPSILON/2, 0)

Это обеспечит y+x == y для любого y >= 1.0.

3 голосов
/ 31 января 2012

Зависит от режимов округления.Вот простой пример.Предположим, что наша точность составляет 4 бита, и мы имеем какое-то представление IEEE754.Таким образом, значение 1 сохраняется как 1,0000 × 2 0 .Следующее большее число равно 1,0001 × 2 0 , а эпсилон ε машины определяется как разница между ними, которая составляет 0,0001 × 2 0 = 1,0000 × 2 -4 .Сейчас:

  • ε / 2 = 1,0000 × 2 -5 = 0,00001 и

  • ε / 4 = 1,0000× 2 −6 = 0,000001.

При добавлении одного из двух к 1 числа сначала переписываются для степени 2 0 и округляется до 4 цифр после разделителя.Выжившая мантисса ε / 4, безусловно, равна 0,0000, в то время как выживающая мантисса ε / 2 равна либо 0,0000, либо 0,0001, в зависимости от того, округляете ли вы вверх или вниз.

Пока эффективная результирующая мантисса равна 0,0000,Вы можете добавить число к 1, не меняя его значения.

(Фактические значения точности 23 + 1, 52 + 1 и 64 для одинарных, двойных и расширенных чисел с плавающей двойной точностью.)

...