Это связано с арифметикой с плавающей точкой c. Это может быть трудно объяснить, если вы не просто «получите» это.
С чего мне начать? Целые числа довольно легко представить в битах, которые понимает процессор. Таким образом, 00000101 интерпретируется как 5 - а именно 5 - потому что это 2 ^ 2 + 2 ^ 0.
Однако это не работает для дробных частей чисел. Чтобы решить эту проблему, ученые-компьютерщики изобрели две формы чисел. Одним из них является то, что я лично считаю BCD (двоично-десятичным), но базы данных называют decimal
или numeric
. Каждый ди git представлен как число. Вам нужно только 4 бита для di git, так что это выглядит так:
0011 0001 1111 0000 1001
3 1 . 0 9
Это точно соответствует 31.09. Просто продолжайте добавлять биты. Примечание: это концептуально. Точная реализация может отличаться.
Второй метод - экспоненциальная запись. То есть: ххх * 2 ^ гггг, где ххх и ггг - целые числа. Например, 0,25 - это 1 * 2 ^ (- 2). «1» и «-2» могут быть точно представлены.
Это хорошо работает для приближений чисел. Проблема в том, что 0,25 может быть точно представлено. Но 0,24 и 0,26 нельзя. Они заканчивают с некоторыми сложными числами, вовлеченными. То же самое относится и к 0,2 - это число, которое вы пытаетесь представить.
В результате получается, что вы пишете 0,2, и оно представляется как 0,00110011001 (скажем). Но когда вы выполняете вычисления, получается 0,00110011000. Оооо. Этот последний бит изменился, поэтому он действительно больше похож на 0.19997 (ну, на практике немного больше 9). Значения не совсем равны.
Мораль: не используйте равенство на числах с плавающей запятой. Числа могут выглядеть одинаково, но различаются в некотором двоичном двоичном десятичном знаке.