Double. Compare To Метод
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Сравнивает данный экземпляр с указанным объектом или объектом Double и возвращает целое число, указывающее, что значение данного экземпляра меньше, больше или равно значению заданного объекта или объекта Double.
Перегрузки
Сравнивает данный экземпляр с указанным объектом и возвращает целое число, которое показывает, является ли значение данного экземпляра меньше, больше или равно значению заданного объекта.
Сравнивает данный экземпляр с заданным числом двойной точности с плавающей запятой и возвращает целое число, которое показывает, является ли значение данного экземпляра меньше, больше или равно значению заданного числа двойной точности с плавающей запятой.
CompareTo(Object)
Сравнивает данный экземпляр с указанным объектом и возвращает целое число, которое показывает, является ли значение данного экземпляра меньше, больше или равно значению заданного объекта.
Параметры
Объект для сравнения или значение null .
Возвращаемое значение
Число со знаком, представляющее относительные значения этого экземпляра и параметра value .
| Значение | Описание |
|---|---|
| Отрицательное целое число | Этот экземпляр меньше value , или этот экземпляр не является числом (NaN), а value является числом. |
| Нуль | Этот экземпляр равен value , или этот экземпляр и value являются Double.NaN , PositiveInfinity или NegativeInfinity. |
| Положительное целое число | Этот экземпляр больше value , ИЛИ этот экземпляр является числом, а value не является числом (NaN), ИЛИ value имеет значение null . |
Реализации
Исключения
value не является объектом типа Double.
Примеры
В следующем примере кода показано использование CompareTo в контексте Double .
Комментарии
Параметр value должен быть null или экземпляром Double ; в противном случае создается исключение. Любой Doubleэкземпляр , независимо от его значения, считается больше. null
Значения должны быть идентичными, которые считаются равными. Особенно если значения с плавающей запятой зависят от нескольких математических операций, они часто теряют точность и для их значений почти идентичны, за исключением их наименее значимых цифр. Из-за этого возвращаемое значение CompareTo метода иногда может показаться удивительным. Например, умножение на определенное значение, за которым следует деление на то же значение, должно создать исходное значение. Однако в следующем примере вычисляемое значение оказывается больше исходного значения. Отображение всех значимых цифр двух значений с помощью строки стандартного числового формата R указывает, что вычисляемое значение отличается от исходного значения в наименее значимых цифрах. Сведения об обработке таких сравнений см. в Equals(Double) разделе "Примечания" метода.
Этот метод реализуется для поддержки IComparable интерфейса. Обратите внимание, что, хотя объект NaN не считается равным другому NaN (даже самому себе), IComparable интерфейс требует, чтобы A.CompareTo(A) возвращать ноль.
Точность в сравнениях
Точность чисел с плавающей запятой за пределами документированной точности зависит от реализации и версии платформа .NET Framework. Следовательно, сравнение двух конкретных чисел может измениться между версиями платформа .NET Framework, так как точность внутреннего представления чисел может измениться.
См. также раздел
Применяется к
CompareTo(Double)
Сравнивает данный экземпляр с заданным числом двойной точности с плавающей запятой и возвращает целое число, которое показывает, является ли значение данного экземпляра меньше, больше или равно значению заданного числа двойной точности с плавающей запятой.
Параметры
Число двойной точности с плавающей запятой для сравнения.
Возвращаемое значение
Знаковое число, представляющее относительные значения этого экземпляра и параметра value .
| Возвращаемое значение | Описание |
|---|---|
| Меньше нуля | Этот экземпляр меньше value , или этот экземпляр не является числом (NaN), а value является числом. |
| Нуль | Этот экземпляр равен value , или и этот экземпляр, и value не являются числом (NaN), PositiveInfinity или NegativeInfinity. |
| Больше нуля | Этот экземпляр больше value , или этот экземпляр является числом, а value не является числом (NaN). |
Реализации
Примеры
В следующем примере кода показаны универсальные и негенерические версии метода для нескольких типов значений CompareTo и ссылок.
Комментарии
Значения должны быть идентичными, которые считаются равными. Особенно если значения с плавающей запятой зависят от нескольких математических операций, они часто теряют точность и для их значений почти идентичны, за исключением их наименее значимых цифр. Из-за этого возвращаемое значение CompareTo метода иногда может показаться удивительным. Например, умножение на определенное значение, за которым следует деление на то же значение, должно создать исходное значение. Однако в следующем примере вычисляемое значение оказывается больше исходного значения. Отображение всех значимых цифр двух значений с помощью строки стандартного числового формата R указывает, что вычисляемое значение отличается от исходного значения в наименее значимых цифрах. Сведения об обработке таких сравнений см. в Equals(Double) разделе "Примечания" метода.
Этот метод реализует System.IComparable<T> интерфейс и немного лучше, Double.CompareTo чем метод, так как ему не нужно преобразовывать value параметр в объект.
Обратите внимание, что, хотя объект, значение NaN которого не считается равным другому объекту, значение которого ( NaN даже само по себе), IComparable<T> интерфейс требует, чтобы A.CompareTo(A) возвращать ноль.
расширяющие преобразования
В зависимости от языка программирования можно закодировать CompareTo метод, в котором тип параметра имеет меньше битов (является более узким), чем тип экземпляра. Это возможно, так как некоторые языки программирования выполняют неявное расширение преобразования, представляющее параметр в качестве типа с таким количеством битов, как экземпляр.
Например, предположим, что тип экземпляра имеет тип Double , а тип параметра — Int32. Компилятор Microsoft C# создает инструкции для представления значения параметра в виде Double объекта, а затем создает метод, который сравнивает Double.CompareTo(Double) значения экземпляра и расширенный представление параметра.
Обратитесь к документации по языку программирования, чтобы определить, выполняет ли компилятор неявное расширение преобразований числовых типов. Дополнительные сведения см. в разделе "Таблицы преобразования типов ".
Точность в сравнениях
Точность чисел с плавающей запятой за пределами документированной точности зависит от реализации и версии платформа .NET Framework. Следовательно, сравнение двух конкретных чисел может измениться между версиями платформа .NET Framework, так как точность внутреннего представления чисел может измениться.
Безопасно ли сравнение == для типа double?
![]()
Нельзя сравнивать два числа с плавующей запятой между собой, из за того, что числа с плавующей запятой не могут быть представлены точно, по-этому мы не можем полагаться на оператор сравнения.
Популярная практика сравнения такая:
Можно задавать свой «эпсилон».
Как я понял, речь идет о MS VC++. Опции компилятора описаны тут https://msdn.microsoft.com/ru-ru/library/e7s85ffb.aspx Если выбрать fast, то не будет соблюдаться стандарт IEEE 754. Не будут работать сравнения с Nan и пр.
Сравнение на строгое равенство почти никогда не безопасно. Вместо него следует использовать fabs(x-y) < EPS , где EPS — это некая константа, например, 1e-7 .
Единственный случай, когда можно позволить себе строгое сравнение — это если есть некая константа, которую ты мог сам присвоить (явно, без вычислений), и с которой сравниваешь для того, чтобы узнать, было ли переприсваивание. И даже в этом месте надо быть осторожным, потому что известны случаи, когда благодаря оптимизации у сравниваемых величин оказывается разный тип, что приводит к разной точности и неравенству.
Ещё все вычисления с целыми числами до 2 53 точные. Это используется языками с единственным числовым типом (например js). Однако, если ты уверен, что значение целое, то зачем вообще использовать double ? Лучше взять 64-битный целый тип.
Как сравнивать double в c
Здравствуйте, gandjustas, Вы писали:
G>Нет. Вообще прямое сравнение чисел с плавающией запятой, вида (a==b) может дать неправильный результат
UN>Не 0.0000001, а EPS — это значение определено в CRT =)
Так. Тут начался беспредел с ужасами про сравнение плавающей точки на равенство. Требуется ликбез. Сравнивать плавающие числа (для педантов — значения переменных типа float или double) вполне можно и даже нужно. Но надо понимать сущность этой плавающей точки. А сущность заключается в том, что числа с фиксированной точкой (целые — это частный случай чисел с фиксированной точкой) имеют абсолютное значение погрешности, в отличие от чисел с плавающей точкой, где значение погрешности находится в прямой пропорциональности от модуля числа. Во всяком случае:
Вот если этот if не сработает, то это означает, что компьютер сломался, а процессор издох.
Другое дело, когда числа вычислены разными способами — одно через синус, а другое — через экспоненту. Здесь действительно проверка на равенство скорее всего не сработает. Так же, как и не сработает сравнение с константой. Но это же относится и к целым числам, если скажем, мы нормализуем значения от 0. 1 к 0. 1000000000. То есть, не имеет значения, плавающие это числа или целые. В определенных ситуациях сравнивать их на строгое равенство нельзя. В этих ситуациях надо использовать некую Epsilon. И вот здесь-то и вылезает наружу вся безграмотность. Что такое DBL_EPSILON? — а это вот что. Это минимальное значение, которое при прибавлении его к единице, меняет значение этой единицы. Понимаете? — к единице! Строгой единице, числу 1.0 и ни к какому другому. Поэтому сравнивать числа с плавающей точкой на +/- DBL_EPSILON совершенно бессмысленно. Это сравнение выдает всю глубину невежества и неспособности думать мозгом. Факты таковы — плавающие числа больше 2.0 эту DBL_EPSILON просто не ощущают. Им что прибавляй ее, что что нет — ничего не меняет. Для этих чисел DBL_EPSILON является строгим нулем и просто не существует. В то же время, DBL_EPSILON имеет значение порядка 1e-16. Что это значит? А это значит, что числа в диапазоне Планковских масштабов (типа 1e-34) с точки зрения этой DBL_EPSILON будут все равны. То есть, эта 1e-16 становится слоном в посудной лавке. А ведь постоянная Планка ничуть не хуже скорости света — для этого собственно и были придуманы числа с плавающей точкой, чтобы отображать большие диапазоны значений с неким фиксированным количеством знаков.
Так для чего же все-таки нужна эта самая DBL_EPSILON (ну или FLT_EPSILON)? Нужна-ли? — нужна! Есть ситуации, когда действительно надо сравнивать числа в неком допустимом интервале. В каком? — А вот это как раз и зависит от абсолютного значения чисел и сущности вычислений. Короче говоря, надо эту Epsilon умножить на значение числа. А поскольку у нас два числа, то все усложняется — какое из них брать. То есть, корректное сравнение выглядит так:
Дорого? Да, дорого, а все остальное неправильно, такие дела. Но и это тоже неправильно! Дело в том, что этот DBL_EPSILON определяет разницу в 1 (один!) значащий бит экспоненты в приложении к числу 1.0. На практике такой разницы не встречается — числа либо строго равны, либо могут различаться больше чем на один значащий бит. Поэтому надо брать что-то типа 16*DBL_EPSILON, чтобы игнрорировать разницу в 4 младших бита (или примерно полторы последние значащие десятичные цифры из примерно 16 имеющихся).
Конечно же, есть случаи, когда диапазон чисел более-менее известен и предсказуем. Скажем, 0. 1000. В этом случае, для сравнения на приблизительное равенство можно взять константу, типа 1000*16*DBL_EPSILON. Но надо иметь в виду, что такое сравнение фактически превращает всю идею плавающей точки в фиксированную точку (догадайтесь, почему).
Я вообще поражен уровню невежества — даже в весьма грамотной библиотеке GPC by Alan Murta используется тупое сравнение с константной Epsilon. На диапазонах экранных координат это все равно, что сравнение на строгое равенство, а на 1e-20 алгоритм вообще перестает работать.
И пожалуйста, имейте смелость высмеять от меня в лицо того университетского преподавателя, который скажет вам, что сравнивать плавающие числа на равенство нельзя. Такое высказывание можно простить в школе, на первом уроке информатики, но никак не в универе.