Это не проблема самого javascript или любого другого языка, а скорее проблема общения между двумя расами, такими как человек и машина, и thinking
сила обеих.То, что кажется нам вполне естественным (например, слово: tree
- когда мы говорим, что создаем абстрактное представление дерева в нашей голове), совершенно не естественно для компьютера, и единственное, что машина может сделать, чтобы обратиться к слову«Древо» - это хранить его в некотором репрезентативном виде, который легко понять на машине (любым способом, который вам действительно нужен, кто-то много лет назад выбрал двоичный код с таблицей ASCII, и он кажется надежным, хотя и сейчас).Итак, в дальнейшем у машины есть представление слова tree
, хранящееся где-то там, скажем, это 00000001
, но оно ничего не знает кроме этого, для вас это имеет какой-то смысл, для машины это просто куча нулейи один.Если затем мы скажем, что для каждого слова может быть максимум 7 битов, потому что в противном случае компьютер работает медленно, тогда машина сохранит 0000000
обрезая последний бит, и поэтому она все равно будет понимать слово tree
в некотором роде.То же самое относится и к числам, 0.3
естественно для вас, но когда вы видите 10101010001010101010101010111
, вы сразу же хотите преобразовать его в десятичную систему, чтобы понять, что оно обозначает, потому что для вас не естественно видеть числа в двоичной системе.И вот здесь главное: преобразование .
И, таким образом, для вас математика выглядит так:
.1 + .2 => .3
Для машины, котораяиспользует двоичную систему выглядит следующим образом:
Число 1/10 может быть выражено как 0,1 в десятичном виде, но это 0,0001100110011001100110011001100110011001100110011001… .. в двоичном.Поскольку для номера в соответствии со стандартом имеется только 53-разрядное пространство, начиная с бита 54, число будет округлено.
x = .1 converted to 00011001...01 and trimmed to 53 bits
y = .2 converted to 00010110...10 and trimmed to 53 bits
z = x + y => 0001100010101... trimmed to 53 bits
result = 0.3000000000000000444089209850062616169452667236328125 converted from z = 0001100010101...
Это похоже на конвертацию евро в доллар, иногдавы получите половину цента, а иногда вы будете платить половину евроцента больше за представление в долларах, потому что не меньше, чем цент.Может быть, но люди сойдут с ума из-за своих карманов.
Таким образом, реальный вопрос - Why does 0.1 converted to binary and trimmed + 0.2 converted to binary and trimmed return unpredictable float results in JavaScript while 0.2 converted to binary and trimmed + 0.3 converted to binary and trimmed does not?
, и ответ таков: из-за математики и количества силы, предоставленной для расчетов, аналогично тому, почему pi + 1
дает странный результат, но 2 + 1
не = => вы, вероятно, поместили некоторое представление числа пи, например 3.1415
, потому что у вас недостаточно математической силы (или не стоит), чтобы получить точный результат.
читайте больше, здесь можно сделать большую часть математики: https://medium.com/dailyjs/javascripts-number-type-8d59199db1b6