Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Bug] Different behavior bytecode/nativecode
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Jon Harrop <jon@j...>
Subject: Re: [Caml-list] [Bug] Different behavior bytecode/nativecode
On Sunday 27 February 2005 00:13, Christophe TROESTLER wrote:
> When I compile the attached program to bytecode, I get the output
> "0.000000 -1.000000 -> 1" (which is correct) but when I compile to
> native code the result is "0.000000 -1.000000 -> 0".
>
> The error stops when I substitute "invw" in "let cr = 300. *. invw
> -. 1.5" by its definition (i.e. if I write
> "let cr = 300. *. (2. /. float w) -. 1.5").
>
> Curious to know what is the problem.

The problem is the conflict of interests between having ocamlc and ocamlopt 
behave identically, and having ocamlopt-compiled code achieve good 
performance. In floating-point code, ocamlopt can sometimes generate slightly 
different results from ocamlc.

Specifically, your code is numerically unstable at the specified values and 
ocamlopt is generating x86 code which is partly performed in 80-bit registers 
(300. *. invw -. 1.5) and partly stored in 64-bit memory locations (2. /. 
float w) whereas ocamlc is storing everything in 64-bit memory locations. 
This leads ocamlc to a result of exactly zero and ocamlopt to a result 
slightly above zero (cr=0.00000000000000003). The rest of the code is then 
numerically unstable with respect to this result.

Inlining the definition of "invw" simply causes the ocamlopt-compiled 
program's computation to be performed entirely at 80-bits, giving the desired 
result of precisely zero:

$ cat >a.ml
let x = 2. /. 400.;;
Printf.printf "%.30f\n" (300. *. x -. 1.5);;
Printf.printf "%.30f\n" (300. *. (2. /. 400.) -. 1.5);;
$ ocamlc a.ml -o a
$ ./a
0.000000000000000000000000000000
0.000000000000000000000000000000
$ ocamlopt a.ml -o a
$ ./a
0.000000000000000031225022567583
0.000000000000000000000000000000

This is described in chapter 4 of "Objective CAML for Scientists":

  http://www.ffconsultancy.com/products/ocaml_for_scientists/

See also "Re: bug in floating point implementation ?" by Xavier Leroy:

  http://caml.inria.fr/caml-list/1147.html

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://ffconsultancy.com