2017-01-23 23 views
0

Предположим, что мы работаем в арифметике с плавающей точкой, с удвоениями, в 64-битной машине. Я хотел бы найти максимальный показатель, для которого существует double a с этим показателем, например, чтоМаксимальный показатель удвоений a, для которого (a - 0,0001) + 0,0001 не равен

(a - 0.0001) + 0.0001 == a 

является ложным.

Я могу привести несколько примеров: a = 5.0e-14 является одним из них. В этом случае

(a - 0.0001) + 0.0001 = 5.0000002510715291e-14 

Я работаю на C++, в случае, если это уместно. Компилятор gcc-4.8.4, без оптимизации.

Справочная информация: В части кода, которую я рассматривал, переменная была сначала сдвинута на 0,0001 для выполнения некоторых вычислений, а сдвинута вверх на 0,0001 с целью восстановления исходного значения. Это не правильный способ сделать это. В идеале я бы просто сохранил исходное значение и скопировал его обратно, вместо того, чтобы делать сдвиг взад и вперед. У разработчика есть надежда, что неассоциативность в плавающей точке не будет иметь никакого существенного эффекта для остальной части кода. Если все такие значения очень близки к 0.0, то это будет верно в нашем случае.

Частичный ответ: Положительные числа с показателем не более -5, то есть 1.0e-5, должны быть примерами.

Partial asnwer 2: 0.00022207040003564455 также является примером и имеет показатель -4.

Есть ли более крупные номера, которые также являются примерами?

+0

Потому что 0,001 не является точно представимым как двоичное число с плавающей запятой, на этот вопрос не будет простой или элегантный ответ. Это особенно важно, потому что способ, которым вы написали свое уравнение, позволяет использовать компилятор в том, как/когда/если он округляет промежуточные значения. Я предлагаю вам дать больше информации о проблеме, которую вы пытаетесь решить. – Sneftel

+0

@Sneftel Проблема точно такая же, как указано. Вопрос о 0,0001, который не является точно представимым, не имеет особого значения. Вы можете предположить, что я написал вместо 0.0001 базовое двоичное число. Просто это число, которое они имеют в коде. Какие аспекты, по вашему мнению, требуют более подробной информации? Версия компилятора? –

+0

Как и в чем, что вам нужно, чтобы иметь возможность делать информацию? Список всех чисел, которые не удовлетворяют вашему уравнению, будет очень длинным, поэтому я не думаю, что это то, что вы ищете. – Sneftel

ответ

1

Гораздо проще охарактеризовать ситуации, в которых результат является правильным, чем те, где это не так.

Во-первых, все номера между 0.00005 и 0.0002 приведут к правильным результатам; по теореме Стербенца результат вычитания может быть точно представлен, а потому, что вход был числом FP, так и результат сложения.

Во-вторых, все числа больше, чем 0.0001/(eps/2) (где eps, в данном случае, DBL_EPSILON будет производить правильные результаты, так как x-0.0001, а затем результат добавляется к 0.0001, будет просто x. (Не слишком взволнованы это связано с миллиардами.)

Кроме того, у вас очень мало возможностей для надежных инвариантов. 0.0001 округленный до числа с плавающей запятой не является хорошим числом: поскольку это не сила 2, результат умножения целочисленного числа малой величины на 2, в его мантиссе много 1s, что позволяет вам рассуждать об этом. Суть в том, что равенство с плавающей запятой равно редко полезная вещь, которую нужно попробовать, и

И даже приведенные выше результаты предполагают две важные вещи: одну (в случае второй привязки), что режим FP является круглым и ближайшим, а два, что все вычисления выполняются с двойной точностью.Первый, который вы почти наверняка можете предположить, если не покончил с собой, чтобы изменить его, но стандарт C++ позволяет выполнять промежуточные результаты в выражении с большей точностью, чем операнды, что означает, что левая сторона может иметь более высокий чем правая сторона, и сравниваться с такой высокой точностью. Это позволяет использовать множество ненулевых битнов мантиссы в левой части, которые правая сторона не может измерить.

В конечном счете, вы можете предположить, что вы группируете числа, которые выполняют или не удовлетворяют вашему уравнению.

+0

Благодарим вас за ответ. Что такое теорема Стербенса? Я не могу найти ссылку с помощью Google. Мне кажется, что это полезно знать. –

+0

В принципе, если 'a' и' b' находятся в 2 раз, 'a-b' точно представляется. – Sneftel

+0

Я обычно слышал это как лемму Стербенца. Здесь также теорема 11 (unattributed) https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html –