ЯвляетсяВозможно иметь `` а <Ь, а не (а - Ь <0) `` с поплавками
a < b and not(a - b < 0)
возможно с плавающей точкой в связи с плавающей запятой раунд ошибки? Есть ли пример?
ЯвляетсяВозможно иметь `` а <Ь, а не (а - Ь <0) `` с поплавками
a < b and not(a - b < 0)
возможно с плавающей точкой в связи с плавающей запятой раунд ошибки? Есть ли пример?
Это зависит от формата с плавающей запятой и, в частности, имеет ли он gradual underflow. Бинарная с плавающей запятой IEEE 754. Это означает, что разрыв между двумя отдельными поплавками всегда отличен от нуля, даже если он может быть представлен только одним значительным битом в крайнем случае.
Наименьшая возможная абсолютная разница между двумя отдельными поплавками имеет знак равенства (или одно из чисел 0), нулевой показатель и значения, отличающиеся на 1. В этом случае вычитание большего из меньшего приведет к наименьшее отрицательное число величины, с отрицательным знаком, нулевой показатель и значение 1. Это число сравнивается меньше нуля.
Существуют другие расчеты, которые выполняют нижнее значение до нуля. Например, деление наименьшего положительного числа на число, большее или равное двум, приводит к нулю в нормальном режиме округления.
Что означает OP, означает 'a < b' and 'a > b'. Потому что 'not (a - b <0)' должен быть 'a> b'. Даже с ошибками округления и ссылкой wiki @ PatriciaShanahan, 'a-b' может быть округлено до 0, если разница меньше наименьшего числа, которое может быть представлено float. Но 'a < b and a > b' состояние кажется невозможным. – FallenAngel
Как проверить, какой формат с плавающей запятой есть? Я запускаю Ubuntu 12.04 с процессором i7-3520M – SlimJim
если IEEE754 => возможно (или нет?) – SlimJim
Вы можете запустить через некоторые из «угловых случаев» легко, как этот
>>> from itertools import product
>>> for a, b in product([0.0, 1.0, float('-inf'), float('inf'), float('nan')], repeat=2):
... print a < b and not(a - b < 0)...
False
False
# and so on
Существует гораздо больше угловых случаев, таких как ± FLT_MIN и ± FLT_MAX, субнормальные числа, отрицательный ноль и т. Д. Это также далека от строгих. Положительный результат был бы неоспоримым, но отрицательные результаты мало что значили. –
@JohnKugelman, Да. поэтому я старался использовать такие слова, как «некоторые» и «как». Очевидно, что добавить список тестов в список легко. Также довольно очевидно, что это не всеобъемлющий тест. –
[Этот ответ предназначен как дополнение педанта к тонкому ответу уже дали Патрисию Shanahan. Этот ответ охватывает нормальный случай; здесь мы беспокоимся о краях, которые вряд ли встречаются на практике.]
Да, это вполне возможно. Вот сессия Python с моим очень обычным, Intel на основе Mac ноутбука:
Enthought Canopy Python 2.7.6 | 64-bit | (default, Jan 29 2014, 17:09:48)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import evil
>>> a = float.fromhex('1p-1022')
>>> b = float.fromhex('1.01p-1022')
>>> a < b and not(a - b < 0)
True
Конечно, как импорт показывает, что есть что-то зло здесь происходит. Вот содержимое evil.py
. (Предупреждение: это очень специфично для платформы, и, как написано, будет работать только на OS X. Вариации этого должны работать на Linux/x64 при условии, что Python был скомпилирован для использования инструкций SSE2 вместо блока x87 для операций с плавающей запятой . Я понятия не имею о Windows.)
# Being lazy: we should really import just the things we need.
from ctypes import *
# Type corresponding to fenv_t from fenv.h. (Platform specific!)
class fenv_t(Structure):
_fields_ = [("control", c_ushort), ("status", c_ushort),
("mxcsr", c_uint), ("reserved", c_char * 8)]
# Wrap fegetenv and fesetenv from the C library.
libc = CDLL("/usr/lib/libc.dylib")
fegetenv = libc.fegetenv
fegetenv.restype, fegetenv.argtypes = c_int, (POINTER(fenv_t),)
fesetenv = libc.fesetenv
fesetenv.restype, fesetenv.argtypes = c_int, (POINTER(fenv_t),)
# Set the flush-to-zero (FTZ) bit in the MXCSR control register.
env = fenv_t()
fegetenv(pointer(env))
env.mxcsr |= 1 << 15
fesetenv(pointer(env))
Так что мы делаем здесь, баловаться с настройками ФПУ, проведенных в регистре управления MXCSR. На процессорах Intel 64, поддерживающих наборы инструкций SSE, есть два интересных флага, которые влияют на поведение операций с субнормальными числами. Флаг FTZ (flush-to-zero), когда он установлен, вызывает какой-либо субнормальный вывод арифметической операции, подлежащей замене на ноль. Флаг DAZ (denormals-is-zero), когда он установлен, вызывает любой субнормальный вход в арифметическую операцию, которая должна обрабатываться так, как если бы она была равна нулю. Суть этих флагов заключается в том, что они могут значительно ускорить операции с субнормальными числами за счет снижения соответствия стандарту IEEE 754. В приведенном выше коде мы установили флаг FTZ в регистр управления MXCSR.
И теперь мы выбираем a
и b
так, что оба a
и b
являются нормальными, но их разность субнормальна. Тогда a < b
будет правдой (как обычно), но a - b
будет -0.0
, а сравнение a - b < 0
не удастся.
Точка вылета заключается в том, что недостаточно того, что формат с плавающей запятой вы используете формат IEEE 754. Вам также необходимо знать, что ваши действия соответствуют стандарту. Режим FTZ является примером того, как это может произойти. Чтобы связать это с ответом Патрисии Шанахан: код в evil.py
отключает постепенное переполнение, которое обещает IEEE 754. (Спасибо @EricPostpischil за указание на это в комментариях.)
Чтобы извлечь ключевой момент для читателей: код в 'evil.py' отключает * постепенное переполнение *, что [ответ Патрисии Шанахан] (http://stackoverflow.com/a/21591038/298225) говорит, что это гарантирует хорошее поведение , Существуют платформы, где это плохое поведение по умолчанию. –
@EricPostpischil: Спасибо; Я впитал некоторые ваши комментарии в ответ. –
У меня нет определенного ответа, но я собираюсь догадаться, абсолютно. Я считаю, что это зависит от единицы с плавающей точкой машины, на которой запущен Python. –
Как странно, как математика с плавающей запятой, я собираюсь выйти на конечность и сказать «Нет», это невозможно. – mhlester
Если поплавками являются бинарные поплавки IEEE 754, денормализация должна предотвращать это условие. –