Как сравнить тип данных double/float в условии?
Пишу:
if($arr[‘P’] == 0.5)
не работает. не попадает в выборку данный массив. как правильно сравнивать подобный тип данных и с чем может быть связана проблема?
UPD:
Как оказалось, проблема не в этом, а в невозможности сравнивать сразу 3 условия, если сравниваю любые другие два, то все работает. Не понимаю, в чем дело.
- Вопрос задан более трёх лет назад
- 5590 просмотров
Комментировать
Решения вопроса 1
gelirgwenn @gelirgwenn
Вы некорректно сравниваете числа типа float. Все числа хранятся в двоичном представлении на компьютере, так уж заведено, выбрана такая система счисления, потому что информацию в виде нулей и единиц легче обрабатывать и легче делать чипы и т.п.
Так вот некоторые числа не имеют точного представления в двоичной системе. Например, 0,2 имеет вид примерно такой 0,2000000033. Соответственно, при сравнении в лоб, вы не сможете гарантировать корректный результат. Вы можете, к примеру, пробовать сравнивать сравнивать разницу с допустимой абсолютной погрешностью:
if (abs($x – $y) < 0.0001) < // Do something. >
Недостаток данного метода описан здесь, а также другие способы сравнения.
Я бы вам рекомендовал перевести float в целое число или строку. В первом случае вы будете сравнивать два целых числа и у вас не будет проблем, во втором — с помощью функции number_format и заданной точности вы преобразуете число в строку, а далее можете сравнивать строки, содержащие числа, с помощью функции bccomp или аналога:
$x = 0.200000000646456546; $y = 0.200000000676790909; $results = ($x == $y); var_dump($results); // bool(false) $results = bccomp(number_format($x, 5), number_format($y, 5)); var_dump($results); // int(0) - are equal
Сравнение чисел с плавающей точкой
Известно, что числа с плавающей точкой нельзя сравнивать с помощью ==. Однако, нет ли исключения из этого правила? Дело вот в чём. Если мы вводим значение такой переменной (которое заведомо не будет за пределами точности), а потом сравниваем с некоторыми такими же «чистыми» значениями с помощью ==, это будет адекватно? Можно ли так делать, и если нельзя, то почему?
1 2 3 4 5 6 7 8 9 10
float a; cin >> a; if (a==1) cout "raz" endl; if (a==2) cout "dva" endl; //вроде ничего криминального не должно быть, если вводим, например, единицу
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Написать защиту от ввода чисел с плавающей точкой, отрицательных чисел и символов
Привет всем! Вот пишу программу, преподаватель сказал чтобы написал защиту от ввода чисел с.
Умножения чисел с плавающей точкой
Доброго времени суток,нужна ваша помощь в умножение чисел с плавающей точкой. Суть.
Массив чисел с плавающей точкой
#include <iostream> #include <ctime> #include <fstream> using namespace std; int main() < .
Представление чисел с плавающей точкой
Никак не пойму почему в коде: double helper; bool cond; int dim_2; int dim_1;.
![]()
![]()
5277 / 2364 / 342
Регистрация: 20.02.2013
Сообщений: 5,763
Записей в блоге: 20
Сообщение от mariko_11 
числа с плавающей точкой нельзя сравнивать с помощью ==
Почему это?
Регистрация: 11.03.2013
Сообщений: 64
Но дело в том, что единица с клавиатуры в переменную и единица из литерала запишутся вроде бы точно. Значит, иногда можно таки сравнивать ?
![]()
![]()
5277 / 2364 / 342
Регистрация: 20.02.2013
Сообщений: 5,763
Записей в блоге: 20
Сообщение от mariko_11 
Точность же.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#include int main() { float a; std::cout "Enter your number (it shall be a float value): "; std::cin >> a; if (a == 1.0) std::cout "drug" std::endl; else if (a == 2.0) std::cout "vrag" std::endl; else std::cout "i ne drug, i ne vrag, a tak: " a std::endl; return 0; }
Прекрасно же работает всё.
Регистрация: 11.03.2013
Сообщений: 64
Да ничё. Единица с клавиатуры в переменную (в моём примере) и единица из литерала запишутся вроде бы точно. Значит, иногда можно таки сравнивать ?
А что код работает — ну извиняйте, ещё не гарантия, что ошибок там нет.
Упд. Ах едрииить, там же не 1.0, а 1. Что там с приведением типов при сравнении? Тут ошибки нет?
![]()
![]()
5277 / 2364 / 342
Регистрация: 20.02.2013
Сообщений: 5,763
Записей в блоге: 20
Сообщение от mariko_11 
Единица с клавиатуры в переменную (в моём примере) и единица из литерала запишутся вроде бы точно.
А с чего бы быть по-другому?
Сообщение от mariko_11 
Значит, иногда можно таки сравнивать?
По мне, так всегда можно сравнивать. Никак не возьму в толк, в чём у Вас проблема. Предложенный Вами код вполне корректно работает.
Регистрация: 11.03.2013
Сообщений: 64
А с чего бы быть по-другому?
А везде пишут, что нельзя. Но если подумать, получается, что в таких-то случаях можно.
Ещё вопрос: какого типа переменные в результате будут сравниваться в if (a==1)? Чтобы что-то сравнить, надо привести это к одному типу. К чему тут автоматически приведётся ?
![]()
![]()
5277 / 2364 / 342
Регистрация: 20.02.2013
Сообщений: 5,763
Записей в блоге: 20
Сообщение от mariko_11 
везде пишут, что нельзя
Регистрация: 11.03.2013
Сообщений: 64
По мне, так всегда можно сравнивать. Никак не возьму в толк, в чём у Вас проблема. Предложенный Вами код вполне корректно работает.
Не всегда же (там для пхп, но разницы никакой) http://oooportal.ru/?cat=article&id=87
![]()
![]()
5277 / 2364 / 342
Регистрация: 20.02.2013
Сообщений: 5,763
Записей в блоге: 20
Сообщение от mariko_11 
Чтобы что-то сравнить, надо привести это к одному типу. К чему тут автоматически приведётся ?
К float, надо полагать. Я так думаю.
Регистрация: 11.03.2013
Сообщений: 64
Добавлено через 9 минут
Про приведение при сравнении. Ну там может в стандарте кто чего видел или в приличных учебниках. Не ищется ни в какую.
![]()
![]()
5277 / 2364 / 342
Регистрация: 20.02.2013
Сообщений: 5,763
Записей в блоге: 20
Отталкивался от объяснений Стивена Праты:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
// typecast.cpp -- -- принудительное изменение типов #include int main() { using namespace std; int auks, bats, coots; // следующий оператор суммирует значения типа double, // а полученный результат преобразуется в тип int auks = 19.99 + 11.99; // эти операторы суммируют целочисленные значения bats = (int) 19.99 + (int) 11.99; // старый синтаксис С coots = int (19.99) + int (11.99); // новый синтаксис C++ cout "auks = " auks ", bats = " bats; cout ", coots = " coots endl; char ch = 'Z'; cout "The code for " ch " is "; // вывод в формате char cout int(ch) endl; // вывод в формате int cout "Yes, the code is "; cout static_castint>(ch) endl; // использование static_cast // cin.get(); return 0; }
Как сравнить float с 0
Привет всем!
Есть два числа типа float,
одно содержит 0.50000002607703
другое — 0.50000000000000
Как мне их сравнить, так чтобы в сравнении участвовали только две цифры после запятой
Take it easy.
Re: Сравнение float
| От: | Kaa | http://blog.meta.ua/users/kaa/ |
| Дата: | 19.02.02 16:24 | |
| Оценка: |
Здравствуйте Yuri, Вы писали:
Y>Привет всем!
Y>Есть два числа типа float,
Y>одно содержит 0.50000002607703
Y>другое — 0.50000000000000
Y>Как мне их сравнить, так чтобы в сравнении участвовали только две цифры после запятой
Первое, что приходит в голову — умножить на 100 (на 10 в степени кол-ва нуждных тебе разрядов, в этом случае — 2). и отбросить дробную часть, и сравнить. Или, после умножения вычесть меньшее из большего, и сравнить разность. Если она меньше единицы — все хорошо, это оно.
Алексей Кирдин
Re[2]: Сравнение float
| От: | Sergey |
| Дата: | 19.02.02 16:36 |
| Оценка: |
Здравствуйте Kaa, Вы писали:
Kaa>Здравствуйте Yuri, Вы писали:
Y>>Привет всем!
Y>>Есть два числа типа float,
Y>>одно содержит 0.50000002607703
Y>>другое — 0.50000000000000
Y>>Как мне их сравнить, так чтобы в сравнении участвовали только две цифры после запятой
Kaa>Первое, что приходит в голову — умножить на 100 (на 10 в степени кол-ва нуждных тебе разрядов, в этом случае — 2). и отбросить дробную часть, и сравнить.
Так делать нельзя. Например, сравни 2.9999999999 и 3.000000000
Kaa>Или, после умножения вычесть меньшее из большего, и сравнить разность. Если она меньше единицы — все хорошо, это оно.
А вот это уже правильно, только умножать незачем — вычесть, сравнить с допустимой ошибкой.
Одним из 33 полных кавалеров ордена «За заслуги перед Отечеством» является Геннадий Хазанов.
Re: Сравнение float
| От: | Кодт |
| Дата: | 19.02.02 16:36 |
| Оценка: |
Здравствуйте Yuri, Вы писали:
Y>Привет всем!
Y>Есть два числа типа float,
Y>одно содержит 0.50000002607703
Y>другое — 0.50000000000000
Y>Как мне их сравнить, так чтобы в сравнении участвовали только две цифры после запятой
1) округление до 0.01
inline double round_to(double value, double eps) < assert(eps >0); return floor(value/eps + 0.5) * eps; > inline int compare_1(double a, double b, double eps) < double diff = floor(a/eps + 0.5) - floor(b/eps + 0.5); return diff < 0 ? -1 : diff >0 ? +1 : 0; > compare_1(0.5123, 0.5145, 0.01); diff = floor(51.23 + 0.5) - floor(51.45 + 0.5) == 51-51 = 0
2) числа в окрестности +/- 1% считать равными
inline double compare_2(double a, double b, double eps) < double diff = round_to( (a - b) * 2 / (a + b), eps); return diff < 0 ? -1 : diff >0 ? +1 : 0; > compare_2(0.000512, 0.000534, 0.01) diff = round_to( -0.000022 / 0.000522, 0.01 ) = round_to( -0.0421. 0.01 ) = -0.04 compare_2(0.0005123, 0.0005145, 0.01) diff = round_to( -0.0000022 / 0.0005122, 0.01 ) = round_to( -0.00429. 0.01 ) = 0
Перекуём баги на фичи!
Re[3]: Сравнение float
| От: | Kaa | http://blog.meta.ua/users/kaa/ |
| Дата: | 19.02.02 16:42 | |
| Оценка: |
Здравствуйте Sergey, Вы писали:
Чего к словам придираться. Все всё поняли. Дело в алгоритме.
Kaa>>Первое, что приходит в голову — умножить на 100 (на 10 в степени кол-ва нуждных тебе разрядов, в этом случае — 2). и отбросить дробную часть, и сравнить.
S> Так делать нельзя. Например, сравни 2.9999999999 и 3.000000000
299.0 != 300.0, что и требовалось доказать. Что не так? В чем «нельзя»?
Kaa>>Или, после умножения вычесть меньшее из большего, и сравнить разность. Если она меньше единицы — все хорошо, это оно.
S> А вот это уже правильно, только умножать незачем — вычесть, сравнить с допустимой ошибкой.
Можно и не умножать. Тогда погрешность (допустимую ошибку) знать надо.
Алексей Кирдин
Re[4]: Сравнение float
| От: | Sergey |
| Дата: | 19.02.02 16:54 |
| Оценка: |
Здравствуйте Kaa, Вы писали:
Kaa>Здравствуйте Sergey, Вы писали:
Kaa>Чего к словам придираться. Все всё поняли. Дело в алгоритме.
Kaa>>>Первое, что приходит в голову — умножить на 100 (на 10 в степени кол-ва нуждных тебе разрядов, в этом случае — 2). и отбросить дробную часть, и сравнить.
S>> Так делать нельзя. Например, сравни 2.9999999999 и 3.000000000
Kaa>299.0 != 300.0, что и требовалось доказать. Что не так? В чем «нельзя»?
Ты всерьез полагаешь, что человеку надо именно это — два числа, отличающиещиеся на 0.0е-10, считать разными? Если да, то можно просто битмаской лишнее прихлопнуть (сколько там двоичных знаков, сразу и не соображу) и сравнивать — будет типа очень быстро
Kaa>>>Или, после умножения вычесть меньшее из большего, и сравнить разность. Если она меньше единицы — все хорошо, это оно.
S>> А вот это уже правильно, только умножать незачем — вычесть, сравнить с допустимой ошибкой.
Kaa>Можно и не умножать. Тогда погрешность (допустимую ошибку) знать надо.
Kaa>С уважением
Одним из 33 полных кавалеров ордена «За заслуги перед Отечеством» является Геннадий Хазанов.
Re: Сравнение float
| От: | Курилка | http://kirya.narod.ru/ |
| Дата: | 19.02.02 17:04 | |
| Оценка: | +1 | |
Здравствуйте Yuri, Вы писали:
Y>Привет всем!
Y>Есть два числа типа float,
Y>одно содержит 0.50000002607703
Y>другое — 0.50000000000000
Y>Как мне их сравнить, так чтобы в сравнении участвовали только две цифры после запятой
Re[5]: Сравнение float
| От: | Kaa | http://blog.meta.ua/users/kaa/ |
| Дата: | 19.02.02 17:11 | |
| Оценка: |
Здравствуйте Sergey, Вы писали:
S> Ты всерьез полагаешь, что человеку надо именно это — два числа, отличающиещиеся на 0.0е-10, считать разными? Если да, то можно просто битмаской лишнее прихлопнуть (сколько там двоичных знаков, сразу и не соображу) и сравнивать — будет типа очень быстро
Вопрос перечитай, что-ли. Ему надо, в твоих терминах, отождествить 2 числа с одинаковыми первыми тремя разрядами при равным показателем степени в стандартной заприси числа.
Алексей Кирдин
Re[6]: Сравнение float
| От: | Sergey |
| Дата: | 20.02.02 08:04 |
| Оценка: |
Здравствуйте Kaa, Вы писали:
Kaa>Здравствуйте Sergey, Вы писали:
S>> Ты всерьез полагаешь, что человеку надо именно это — два числа, отличающиещиеся на 0.0е-10, считать разными? Если да, то можно просто битмаской лишнее прихлопнуть (сколько там двоичных знаков, сразу и не соображу) и сравнивать — будет типа очень быстро
Kaa>Вопрос перечитай, что-ли. Ему надо, в твоих терминах, отождествить 2 числа с одинаковыми первыми тремя разрядами при равным показателем степени в стандартной заприси числа.
Перечитал. По вопросу совершенно непонятно, что ж ему все-таки надо. Так что если ему это еще надо, пусть задает вопрос по новой
Одним из 33 полных кавалеров ордена «За заслуги перед Отечеством» является Геннадий Хазанов.
Re[2]: Сравнение float
| От: | Kaa | http://blog.meta.ua/users/kaa/ |
| Дата: | 20.02.02 13:18 | |
| Оценка: |
Здравствуйте Курилка, Вы писали:
К>Здравствуйте Yuri, Вы писали:
Y>>Привет всем!
Y>>Есть два числа типа float,
Y>>одно содержит 0.50000002607703
Y>>другое — 0.50000000000000
Y>>Как мне их сравнить, так чтобы в сравнении участвовали только две цифры после запятой
К>я дак делаю fabs(val1-val2) К>где delta — необходимая точность
Это немного не то. Вот тебе пример:
2.99092 -> 2.99 != 3.00 -> 3.00, хотя при этом |2.99092 — 3.00| < 0.01
Короче говоря, требуется совпадение разрядов, а не просто их близость на числовой прямой.
Алексей Кирдин
Re[3]: Сравнение float
| От: | Курилка | http://kirya.narod.ru/ |
| Дата: | 20.02.02 13:38 | |
| Оценка: |
Здравствуйте Kaa, Вы писали:
Kaa>Здравствуйте Курилка, Вы писали:
К>>Здравствуйте Yuri, Вы писали:
Y>>>Привет всем!
Y>>>Есть два числа типа float,
Y>>>одно содержит 0.50000002607703
Y>>>другое — 0.50000000000000
Y>>>Как мне их сравнить, так чтобы в сравнении участвовали только две цифры после запятой
К>>я дак делаю fabs(val1-val2) К>>где delta — необходимая точность
Kaa>Это немного не то. Вот тебе пример:
Kaa>2.99092 -> 2.99 != 3.00 -> 3.00, хотя при этом |2.99092 — 3.00| < 0.01
Kaa>Короче говоря, требуется совпадение разрядов, а не просто их близость на числовой прямой.
И кому такое сравнение нужно. Стесняюсь спросить.
тогда и 2.9901 будет равно 3.0099?
по-моему для нормальной задачи это бред
Re[4]: Сравнение float
| От: | Kaa | http://blog.meta.ua/users/kaa/ |
| Дата: | 20.02.02 13:45 | |
| Оценка: | 1 (1) | |
Здравствуйте Курилка, Вы писали:
Y>>>>Привет всем!
Y>>>>Есть два числа типа float,
Y>>>>одно содержит 0.50000002607703
Y>>>>другое — 0.50000000000000
Y>>>>Как мне их сравнить, так чтобы в сравнении участвовали только две цифры после запятой
Это видел?
Kaa>>Это немного не то. Вот тебе пример:
Kaa>>2.99092 -> 2.99 != 3.00 -> 3.00, хотя при этом |2.99092 — 3.00| < 0.01
Kaa>>Короче говоря, требуется совпадение разрядов, а не просто их близость на числовой прямой.
К>И кому такое сравнение нужно. Стесняюсь спросить.
Ему нужно, спрашивающему.
К>тогда и 2.9901 будет равно 3.0099?
Когда — «тогда». Отождествляются только чиса с первыми тремя разрядами. В твоем примере это не так. Разряды различаются. Так, напимер, можно сравнивать деньги: целые — рубли, дробные — копейки. Без большой точности. Это, ты считаешь, не реальная задача? )
Алексей Кирдин
Re[5]: Сравнение float
| От: | Курилка | http://kirya.narod.ru/ |
| Дата: | 20.02.02 13:51 | |
| Оценка: |
Здравствуйте Kaa, Вы писали:
К>>тогда и 2.9901 будет равно 3.0099?
Kaa>Когда — «тогда». Отождествляются только чиса с первыми тремя разрядами. В твоем примере это не так. Разряды различаются.
сорри, я имел в виду 2.9999 != 3.00
вечно пишу совсем не то, что думаю
Kaa>Так, напимер, можно сравнивать деньги: целые — рубли, дробные — копейки. Без большой точности. Это, ты считаешь, не реальная задача? )
наверно ты прав, хотя на мой взгляд это тоже спорно, как деньги округлять.
Re[6]: Сравнение float
| От: | Кодт |
| Дата: | 21.02.02 10:16 |
| Оценка: |
Здравствуйте Курилка, Вы писали:
К>Здравствуйте Kaa, Вы писали:
К>>>тогда и 2.9901 будет равно 3.0099?
Kaa>>Когда — «тогда». Отождествляются только чиса с первыми тремя разрядами. В твоем примере это не так. Разряды различаются.
К>сорри, я имел в виду 2.9999 != 3.00
К>вечно пишу совсем не то, что думаю
Kaa>>Так, напимер, можно сравнивать деньги: целые — рубли, дробные — копейки. Без большой точности. Это, ты считаешь, не реальная задача? )
К>наверно ты прав, хотя на мой взгляд это тоже спорно, как деньги округлять.
Перекуём баги на фичи!
Re[7]: Сравнение float
| От: | Sergey | |
| Дата: | 21.02.02 10:39 | |
| Оценка: | 1 (1) | |
А вот это, конечно, дело темное Но, опять же, нафига в них сравнивать числа, отбрасывая младшие разряды? Разве что для скорости.
Одним из 33 полных кавалеров ордена «За заслуги перед Отечеством» является Геннадий Хазанов.
Re[8]: Сравнение float
| От: | Кодт |
| Дата: | 24.02.02 13:08 |
| Оценка: |
Например, соотношение сигнал/шум составляет 1:0.01.
Какой тогда смысл снимать с АЦП больше 2 разрядов?
Это не просто отбрасывание. Это сглаживание.
Перекуём баги на фичи!
Re[9]: Сравнение float
| От: | Sergey | |
| Дата: | 26.02.02 09:25 | |
| Оценка: | 10 (1) | |
Можно поподробнее? Что и как тут сглаживается (чем отбрасывание лучше сглаживания, если не принимать в расчет быстродействие)?
Одним из 33 полных кавалеров ордена «За заслуги перед Отечеством» является Геннадий Хазанов.
Re[10]: Сравнение float
| От: | Кодт |
| Дата: | 26.02.02 13:02 |
| Оценка: |
Здравствуйте Sergey, Вы писали:
К>>Банковское округление — это, грубо говоря, 0.04 —> 0.0, 0.05 —> 0.1,
К>>т.е. ошибка составляет 0.05 вместо 0.10. Тем не менее, она накапливается.
S> Не, не так прямолинейно. «Банковское округление» — это, например (есть, вроде бы, несколько способов) когда 1.05 -> 1.1,
S>а 2.05 -> 2.0. Если сумма цифр четная и последняя цифра — пятерка, округляем в одну сторону, нечетная — в другую. Ошибка не накапливается, если числа можно считать случайными.
Да, насчет шума квантования — недодумал.
Вычисления — пожалуйста, с большой точностью.
Все тот же шум квантования.
Перекуём баги на фичи!
Re[11]: Сравнение float
| От: | Sergey |
| Дата: | 26.02.02 13:25 |
| Оценка: |
Здравствуйте Кодт, Вы писали:
К>Здравствуйте Sergey, Вы писали:
К>>>Банковское округление — это, грубо говоря, 0.04 —> 0.0, 0.05 —> 0.1,
К>>>т.е. ошибка составляет 0.05 вместо 0.10. Тем не менее, она накапливается.
S>> Не, не так прямолинейно. «Банковское округление» — это, например (есть, вроде бы, несколько способов) когда 1.05 -> 1.1,
S>>а 2.05 -> 2.0. Если сумма цифр четная и последняя цифра — пятерка, округляем в одну сторону, нечетная — в другую. Ошибка не накапливается, если числа можно считать случайными.
К>А если не случайными?
Ну так он при отбрасывании разрядов просто увеличится. А вообще, по крайней мере в КИХ-фильтрах, IMHO, сравнивать ничего не требуется. Знай себе умножай да складывай.
Одним из 33 полных кавалеров ордена «За заслуги перед Отечеством» является Геннадий Хазанов.
Re: Сравнение float
| От: | artgonch |
| Дата: | 01.09.04 14:58 |
| Оценка: |
Здравствуйте!
Извините, что снова поднимаю эту тему. Есть такой код:
const float delta = 0.001f; for (int i = 0; i < GetCount(); ) < GetRecord(i); //if (m_f1 < f)if (fabs(m_f1 - f) < delta) DeleteRecord(i); else i++; >
Использую VS.NET 2002. Фугкция DeleteRecord() не вызыввется даже когда разность меньше погрешности. В чем может быть причина?
Сравнение вещественных чисел float в Golang
При работе с вещественными числами, или числами с плавающей запятой, могут быть несоответствия при сравнении двух значений, что кажутся одинаковыми. В отличие от целых чисел, IEEE вещественные значения являются «приблизительными». Необходимость конвертации чисел в подходящую для хранения в памяти компьютера форму приводит к небольшим неточностям вследствие округления. К примеру, значение 1.3 может быть представлено в виде 1.29999999999. Сравнение может осуществляться с допустимым отклонением. Для сравнения чисел с произвольной точностью нужен пакет big.
Как сравнить вещественные числа float в Go?
1. Создайте файл tolerance.go со следующим содержимым:

Премиум канал по Golang
Рекомендуем вам супер TELEGRAM канал по Golang где собраны все материалы для качественного изучения языка. Удивите всех своими знаниями на собеседовании!
Уроки, статьи и Видео
Мы публикуем в паблике ВК и Telegram качественные обучающие материалы для быстрого изучения Go. Подпишитесь на нас в ВК и в Telegram. Поддержите сообщество Go программистов.
tolerance.go
package main
const da = 0.29999999999999998889776975374843459576368331909180
const db = 0.3
daStr : = fmt . Sprintf ( «%.10f» , da )
dbStr : = fmt . Sprintf ( «%.10f» , db )
// Во время форматирования числа в строку
// оно округляется до 3.
fmt . Printf ( «Строки %s = %s равны: %v \n» , daStr , dbStr , dbStr == daStr )
// Числа не равны
fmt . Printf ( «Числа равны: %v \n» , db == da )
// Точность вещественных значений
// ограничена. Для сравнения float
// лучше использовать сравнение с допуском.
fmt . Printf ( «Числа равны с учетом ДОПУСКА: %v \n» , Equals ( da , db ) )
const TOLERANCE = 1e — 8
// Equals сравнивает вещественные числа
// с допуском 1e-8
func Equals ( numA , numB float64 ) bool <
delta : = math . Abs ( numA - numB )
if delta < TOLERANCE <
return true
return false
2. Запустите код в терминале через go run tolerance.go ;
3. Посмотрите на вывод:
Строки 0.3000000000 = 0.3000000000 равны : true
Числа равны : false
Числа равны с учетом ДОПУСКА : true
4. Создайте файл big.go со следующим содержимым:
package main
var da float64 = 0.299999992
var db float64 = 0.299999991
var prec uint = 32
var prec2 uint = 16
fmt . Printf ( «Сравнение float64 с ‘==’ равно: %v\n» , da == db )
daB : = big . NewFloat ( da ) . SetPrec ( prec )
dbB : = big . NewFloat ( db ) . SetPrec ( prec )
fmt . Printf ( «A: %v \n» , daB )
fmt . Printf ( «B: %v \n» , dbB )
fmt . Printf ( «Сравнение big.Float с точностью: %d : %v\n» , prec , daB . Cmp ( dbB ) == 0 )
daB = big . NewFloat ( da ) . SetPrec ( prec2 )
dbB = big . NewFloat ( db ) . SetPrec ( prec2 )
fmt . Printf ( «A: %v \n» , daB )
fmt . Printf ( «B: %v \n» , dbB )
fmt . Printf ( «Сравнение big.Float с точностью: %d : %v\n» , prec2 , daB . Cmp ( dbB ) == 0 )
5. Запустите код в терминале через go run big.go ;
6. Посмотрите на вывод:
Сравнение float64 с ‘==’ равно : false
A : 0.299999992
B : 0.299999991
Сравнение big .Float с точностью : 32 : false
Сравнение big .Float с точностью : 16 : true
Функции для сравнивания Float между собой в Golang
Первый способ сравнения вещественных чисел без использования встроенных пакетов (шаги 1-5) требует задействования так называемой константы EPSILON . Это небольшое значение разницы (дельты) между числами, что позволит считать их равными. Константа может быть со значением около 1е-8 , чего достаточно для определения точности.
Второй вариант не только более сложный, но и более полезный для дальнейшей работы с вещественными числами. Пакет math/big предлагает тип Float , что можно настроить для данной точности. Преимущество данного пакета в том, что точность здесь может быть выше, нежели точность типа float64 . По этой причине значения небольшой точности использовались для примера округления и сравнения данной точности.
Обратите внимание, что числа da и db равны при использовании 16-битной точности, но не равны при использовании 32-битной точности. Максимальную настраиваемую точность можно получить из константы big.MaxPrec .

Администрирую данный сайт с целью распространения как можно большего объема обучающего материала для языка программирования Go. В IT с 2008 года, с тех пор изучаю и применяю интересующие меня технологии. Проявляю огромный интерес к машинному обучению и анализу данных.
E-mail: vasile.buldumac@ati.utm.md
Образование
Технический Университет Молдовы (utm.md), Факультет Вычислительной Техники, Информатики и Микроэлектроники
- 2014 — 2018 Universitatea Tehnică a Moldovei, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Universitatea Tehnică a Moldovei, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»