Почему 0.0 == 0.0 false в REPL, но true при выполнении в исходном режиме? - PullRequest
0 голосов
/ 24 февраля 2019

0.0 == 0.0 равно false, когда я выполняю это выражение в интерактивном REPL:

$ ocaml
        OCaml version 4.02.3

# 0.0 == 0.0;;
- : bool = false
# 0.0 = 0.0;;
- : bool = true

Но это true, если я компилирую и запускаю эту программу:

let _ =                                                                                                                                                                                                                                                                  
  print_endline (string_of_bool (0.0 == 0.0));
  print_endline (string_of_bool (0.0 = 0.0))

файл дюны:

(executable (name main))

Компиляция и запуск:

$ dune --version
1.0.0
$ dune exec ./main.exe
true
true

Как 0.0 == 0.0 может когда-либо быть false, и почему это будет другое значение при выполнении этого кодаизначально?

1 Ответ

0 голосов
/ 24 февраля 2019

Примечание для начинающих OCaml: «нормальное» равенство равно =.Оператор == проверяет, имеют ли два значения одинаковый адрес памяти.

Оператор == иногда довольно трудно понять.Чтобы процитировать руководство по OCaml:

На не изменяемых типах поведение (==) зависит от реализации;тем не менее, гарантируется, что e1 == e2 подразумевает, что compare e1 e2 = 0.

float не является изменяемым типом, нет гарантии его поведения при двух равных значениях.

Теперь давайте посмотрим, что именно произойдет.

В случае интерпретатора ваши выражения оцениваются без особой оптимизации.Суть в том, чтобы ваш код выполнялся быстро, а не чтобы он работал быстро.Поэтому, когда он видит постоянную 0.0, программы выделяют новый блок физической памяти, который содержит соответствующие данные «float 0.0».Выделите одну и ту же константу два раза, и вы получите два разных адреса памяти.Следовательно, 0.0 == 0.0 возвращает false

Теперь компилятор нативного кода стал намного умнее.Он пытается минимизировать использование памяти и время выполнения.Когда он видит, что одна и та же неизменная константа выделяется два раза, он считает, что «нет смысла выделять одну и ту же вещь дважды, давайте выделять один раз».

В некотором смысле, компилятор превращает 0.0 == 0.0 в let c = 0.0 in c == c.Вот почему вы получаете true.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...