c++ — Как сравнить float и double?

Как правильно сравнивать два числа типа float и double? Следующий способ часто говорит, что одинаковые числа различны:

float a = 0.00001001;
double b = 0.00001001;
if (a == b) {
  std::cout << "equal"; // не выводит equal
}

Мой вопрос отличается от дубликатов тем, что мне нужно знать, как правильно сравнить 2 числа типа float и double на C++, а не почему (не только почему) простое сравнение не работает. В привидённых в дубликатах ответах либо ответы для 2 одинаковых типов, либо не сказано как выбирать epsilon и т.д..

  • c++
  • float
  • сравнение
  • double

1

if (fabs(a - b) <= eps)

где eps — некая маленькая величина, вообще говоря — зависящая от порядка самих чисел, поэтому более корректно

if (fabs(a - b)/ max(fabs(a) + eps, fabs(b) + eps) <= eps)

Пример задания eps:

const
  FuzzFactor = 1000;
  SingleResolutionEps = 1E-7 * FuzzFactor;
  DoubleResolutionEps = 1E-15 * FuzzFactor;

Откуда это берётся — точность float 23 двоичных разряда или 7-8 десятичных, т. е. число имеет 7 верных десятичных цифр, поэтому меньше 1E-7 eps смысла нет делать.

Почему используется множитель FuzzFactor = 1000; — это расширение допуска, чёткого критерия его выбора нет, разработчики этой библиотеки решили так сделать, а вообще множитель можно выбирать в зависимости от желаемой погрешности в младших разрядах.

Для сравнения float и double по правилам сложения погрешностей следует использовать погрешность для менее точных float, т.е. порядка

1E-7 даже при приведении float к double, как предложил в комментарии @Grundy — ведь при этом приведении возникают дополнительные ничем не обеспеченные разряды с погрешностью в пределах всё тех же 1E-7.

Труды по точности float-арифметики: 1 2 Goldberg

14

Машинный эпсилон это одно,а точность входных данных в задаче это совсем другое.
Редко бывает, чтобы точность входных данных в задаче была равна машинному эпсилону.


Обычно точность входных данных в задаче гораздо меньше, чем машинный эпсилон.
Есть целая наука об правилах округления и отбрасывания незначащих цифр.
Исходя из этой науки и выбирается в каждом конкретном случае эпсилон для каждой конкретной задачи.

А машинный эпсилон это характеристика данной вычислительной системы.

Зарегистрируйтесь или войдите

Регистрация через Google

Регистрация через Facebook

Регистрация через почту

Отправить без регистрации

Почта

Необходима, но никому не показывается

Отправить без регистрации

Почта

Необходима, но никому не показывается

Нажимая на кнопку «Отправить ответ», вы соглашаетесь с нашими пользовательским соглашением, политикой конфиденциальности и политикой о куки

Числа с плавающей точкой | Руководство по PHP

Вернуться к: Типы

Числа с плавающей точкой (также известные как «float», «double», или «real») могут быть определены следующими синтаксисами:

Формально:

Размер числа с плавающей точкой зависит от платформы, хотя максимум, как правило составляет ~1. 8e308 с точностью около 14 десятичных цифр (64-битный IEEE формат).

Внимание

Числа с плавающей точкой имеют ограниченную точность. Хотя это зависит от операционной системы, в PHP обычно используется формат двойной точности IEEE 754, дающий максимальную относительную ошибку округления порядка 1.11e-16. Неэлементарные арифметические операции могут давать большие ошибки, и, разумеется, необходимо принимать во внимание распространение ошибок при совместном использовании нескольких операций.

Кроме того, рациональные числа, которые могут быть точно представлены в виде чисел с плавающей точкой с основанием 10, например, 0.1 или 0.7, не имеют точного внутреннего представления в качестве чисел с плавающей точкой с основанием 2, вне зависимости от размера мантиссы. Поэтому они и не могут быть преобразованы в их внутреннюю двоичную форму без небольшой потери точности.

Это может привести к неожиданным результатам: например, floor((0.1+0.7)*10) скорее всего вернет 7 вместо ожидаемого 8, так как результат внутреннего представления будет чем-то вроде 7.9999999999999991118….

Так что никогда не доверяйте точности чисел с плавающей точкой до последней цифры, и не проверяйте напрямую их равенство. Если вам действительно необходима высокая точность, используйте математические функции произвольной точности и gmp-функции.

«Простое» объяснение можно найти в » руководстве по числам с плавающей точкой, которое также называется «Why don’t my numbers add up?» («Почему мои числа не складываются?»)

Преобразование в число с плавающей точкой

Информацию о преобразовании строк в числа с плавающей точкой смотрите в разделе Преобразование строк в числа. Для значений других типов преобразование будет сначала осуществлено в в integer и затем в число с плавающей точкой. Дополнительную информацию смотрите в разделе Преобразование к целому. Начиная с версии PHP 5, при преобразовании объекта к числу с плавающей точкой выводится замечание об ошибке.

Сравнение чисел с плавающей точкой

Как указано выше, проверять числа с плавающей точкой на равенство проблематично из-за их внутреннего представления. Тем не менее, существуют способы для их сравнения, которые работают несмотря на все эти ограничения.

Для сравнения чисел с плавающей точкой используется верхняя граница относительной ошибки при округлении. Эта величина называется машинной эпсилон или единица округления(unit roundoff) и представляет собой самую маленькую допустимую разницу при расчетах.

NaN

Некоторые числовые операции могут возвращать значение, представляемое константой NAN. Данный результат означает неопределенное или непредставимое значение в операциях с плавающей точкой. Любое строгое или нестрогое сравнение данного значения с другим значением, включая его самого, возвратит

FALSE.

Так как NAN представляет собой неограниченное количество различных значений, то NAN не следует сравнивать с другими значениями, включая ее саму. Вместо этого, для определения ее наличия необходимо использовать функцию is_nan().

Вернуться к: Типы

Разница между Float и Double (со сравнительной таблицей)

Float и Double являются типами данных в разделе Тип с плавающей запятой. Числа с плавающей запятой — это действительные числа, содержащие дробную часть. Основное различие между float и double заключается в том, что тип float имеет 32-битное хранилище. С другой стороны, тип double имеет 64-битное хранилище.

Существуют и другие различия между float и double, которые обсуждаются в сравнительной таблице ниже.

Содержание: Float и Double

  1. Сравнительная таблица
  2. Определение
  3. Ключевые отличия
  4. Заключение

Сравнительная таблица

База для сравнения Плавающая Двойная
Точность Одинарная точность. Двойная точность.
Биты 32 бита. 64 бита.
Байт 4 байта. 8 байт.
Приблизительный диапазон от 1.4e-045 до 3.4e+038 от 4.9e-324 до 1.8e+308
Представление битов 1 бит представляет бит знака.
8 бит представляют показатель степени.
23 бита представляют мантиссу.
1 бит представляет знаковый бит.
11-битный показатель степени.
52 бита представляют мантиссу.
Точность Менее точная. Более точный.

Определение числа с плавающей запятой

Тип данных с плавающей точкой является одним из типов с плавающей запятой. Тип данных float имеет 32-битное хранилище (что равно 4 байтам) для переменной типа float. Тип данных float указывает одинарную точность. Представление 32-битного числа с плавающей запятой можно объяснить тем, что 1 бит представлен как бит знака, 8 бит представлен как экспонента, а 23 бита представлены как мантисса.

Максимальный диапазон поплавкового типа: от 1.4e-045 до 3.4e+038. По сравнению с двойным типом с плавающей запятой тип float менее точен при математическом расчете. Давайте разберемся с float на примере.

 #include 
#include 
интервал основной () {
число с плавающей запятой1 = sqrt (64,23)
cout << число1;
}
//выход
8.00060 

Как и в приведенном выше коде, вы можете заметить, что переменной с плавающей запятой num1 присваивается значение, равное функции sqrt(), которая возвращает квадратный корень значения, переданного этой функции. Вы можете заметить, что когда печатается значение в num1, оно близко к точному значению, но не является точным. Давайте теперь посмотрим на пример ниже, когда та же программа выполняется с использованием типа данных double.

Определение типа Double

Double — это второй тип типа данных с плавающей запятой. Тип данных double имеет 64-битное хранилище (что равно 8 байтам) для переменной типа double. Он указывает двойную точность, поскольку его размер в два раза больше числа с плавающей запятой. 64-битное представление типа double можно объяснить так: 1 бит представляет бит знака, 11 бит — показатель степени, а оставшиеся 52 бита — мантиссу.

Среди типов float и double наиболее часто используется тип данных double. Тип double используется при математических вычислениях, а также когда требуется абсолютная точность. Математические функции sin(), cos() и sqrt() всегда возвращают двойное значение. Давайте разберемся с точностью типа данных double на примере.

 #include 
#include 
интервал основной () {
двойное число1 = квадрат (64,23)
cout << число1;
}
//выход
8.0143621 

Вы можете заметить, что вывод, полученный в примере с объяснением float, отличается от вывода, полученного в примере с объяснением double. Итак, исходя из этого, мы можем сказать, что результаты, полученные от double, более точны по сравнению с float.


Ключевые различия между числами с плавающей запятой и двойным числом
  1. Тип данных float указывает одинарную точность, что означает, что по сравнению с double он имеет меньшую точность, в то время как double указывает двойную точность, поскольку он просто удвоен для float, его ошибка незначительна по сравнению с float.
  2. Переменная типа float имеет 32-битную память, тогда как переменная типа double имеет 64-битную память, которая при компиляции этой двойной памяти занимает больше места, чем float.
  3. Значение типа float может находиться в диапазоне от 1,4e-045 до 3,4e+038, тогда как значение типа double может находиться в диапазоне от 4,9.е-324 до 1,8е+308.
  4. Битовое представление значения с плавающей запятой похоже на то, что 1 бит с плавающей запятой используется для единичного бита, 8 бит для экспоненты и 23 бита для хранения мантиссы. С другой стороны, двойное значение похоже на то, что 1 его бит используется для единичного бита, 11 бит для экспоненты и 52 бита для хранения мантиссы.
  5. По сравнению с double float менее точен, поэтому используется математический расчет double.

Заключение

Как правило, вы должны использовать двойное число, поскольку оно обеспечивает точность, которая в большинстве случаев является нашим основным преимуществом.

Когда использовать Float против Double с примерами кода

Когда использовать Float против Double с примерами кода

В этом уроке мы будем использовать программирование, чтобы попытаться решить головоломку Когда использовать Float против Double. Это демонстрирует приведенный ниже код.

 - двойная точность выше
- тогда как поплавки занимают меньше памяти и быстрее. 

Ниже вы найдете несколько примеров различных способов решения проблемы «Когда использовать Float против Double».

 Double более точен, чем float, и может хранить 64 бита, что вдвое превышает количество бит, которое может хранить float. Double более точен, и для хранения больших чисел мы предпочитаем double, а не float. Например, для хранения годовой зарплаты генерального директора компании более точным выбором будет значение double. 

Изучив различные случаи из реальной жизни, мы показали, как исправить ошибку «Когда использовать Float против Double».

Когда следует использовать тип данных с плавающей запятой?

Целые числа и числа с плавающей запятой — это два разных типа числовых данных. Целое число (чаще называемое int) — это число без десятичной точки. Число с плавающей запятой — это число с плавающей запятой, что означает, что это число имеет десятичный разряд. Поплавки используются, когда требуется большая точность.

Как узнать, двойное это число или число с плавающей запятой?

Разница между float и double в C/C++ С точки зрения числа точности можно сказать, что double имеет 64-битную точность для числа с плавающей запятой (1 бит для знака, 11 бит для экспоненты и 52* бита для числа с плавающей запятой). value), т. е. double имеет 15 знаков после запятой. 24 февраля 2020 г.

Что точнее: float или double?

double имеет в 2 раза большую точность, чем float. float — это 32-битное число с плавающей запятой одинарной точности IEEE 754 — 1 бит для знака, 8 бит для экспоненты и 23* для значения. float имеет 7 знаков после запятой. 03 августа 2022 г.

В чем разница между float и double?

Число с плавающей запятой имеет точность 7 знаков после запятой и занимает 32 бита. Двойник — это 64-битное число двойной точности IEEE 754 с плавающей запятой. 1 бит для знака, 11 бит для показателя степени и 52 бита для значения. Двойник имеет точность 15 десятичных разрядов и занимает в общей сложности 64 бита.

Зачем использовать float вместо double?

Число с плавающей запятой использует меньше памяти, чем число с двойной точностью, поэтому, если вам не нужно, чтобы ваше число было размером с число с двойной точностью, вы также можете использовать число с плавающей запятой, так как оно займет меньше памяти. Точно так же, как вы не стали бы использовать автобус, чтобы отвезти себя и друга на пляж, вам было бы гораздо лучше поехать на двухместном автомобиле. 11-Jul-2013

В чем разница между типами данных float и double на примере?

Число с плавающей запятой и двойное число Число с плавающей точкой является более точным, чем число с плавающей запятой, и может хранить 64 бита, что вдвое превышает количество бит, которое может хранить число с плавающей запятой. Double более точен, и для хранения больших чисел мы предпочитаем double, а не float. Например, для хранения годовой зарплаты генерального директора компании более точным выбором будет значение double.

double

2.0 float или double?

2.0 — двойное буквальное значение. 2.0f — это литерал с плавающей запятой. 2 — целочисленное буквальное значение. 12 сентября 2010 г.

Является ли 1,5 числом с плавающей запятой или двойным?

И причина успеха сравнения с 1.5 заключается в том, что 1.5 может быть представлено точно как число с плавающей запятой и как двойное; в его младших битах есть куча нулей, поэтому, когда при продвижении добавляются нули, результат будет таким же, как и при представлении типа double.

Число с плавающей запятой быстрее, чем число с плавающей запятой, если вам не нужна двойная точность, и вы ограничены пропускной способностью памяти, а ваше оборудование не имеет штрафа за число с плавающей запятой. Они сохраняют полосу пропускания памяти, поскольку занимают половину места на число.