Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exponential function ** #6835

Closed
vicuna opened this issue Apr 8, 2015 · 3 comments
Closed

Exponential function ** #6835

vicuna opened this issue Apr 8, 2015 · 3 comments

Comments

@vicuna
Copy link

vicuna commented Apr 8, 2015

Original bug ID: 6835
Reporter: igo_weiqi_baduk
Status: closed (set by @xavierleroy on 2016-12-07T10:47:29Z)
Resolution: not a bug
Priority: normal
Severity: minor
Platform: x86_64
OS: Mageia 4
Version: 4.02.1
Category: standard library

Bug description

Using exponential function for some computations I've got :

let n1 = 2. ** 100. ;;

val n1 : float = 1.2676506002282294e+30

let n2 = 2. ** 47. ;;

val n2 : float = 140737488355328.

let n3 = 2. ** 48. ;;

val n3 : float = 281474976710656.

(n1 +. n2) -. n1 ;;

  • : float = 0. <---- ???

(n1 +. n3) -. n1 ;;

  • : float = 281474976710656. <---- OK

In this example, why is n2 completely ignored (and not n3) ?

If this behavior is "correct" , what are the recommended
operations to do in order to get a right result ?

( apart ,of course, writing n1 -. n1 +. n2 which gives the right result
hopefully, but well, this is only a very basic example ).

Rem : with the Num library , all is right

open Num

let num1 = (Int 2 **/ Int 100) ;;

val n1 : Num.num = <num 1267650600228229401496703205376>

let num2 = (Int 2 **/ Int 47) ;;

val n2 : Num.num = <num 140737488355328>

(num1 +/ num2) -/ num1 ;;

  • : Num.num = <num 140737488355328>
@vicuna
Copy link
Author

vicuna commented Apr 8, 2015

Comment author: @damiendoligez

Try it in C (or any other language) and you get the same results. This is how floating-point numbers work.

If this behavior is "correct" , what are the recommended operations to do in order to get a right result ?

There is a whole field of computer science devoted to this question: numerical analysis.

@vicuna
Copy link
Author

vicuna commented Apr 8, 2015

Comment author: @dbuenzli

Remember that the only integers that can be exactly represented by double floating point numbers are those in the interval [-2^53;2^53].

n1 is much larger than that and it so happens that n1 + n2 is represented by n1 while n1 + n3 is not. It also happens that n1 + n3 is precisely represented. But for example n3 + 1 is not:

let n4 = n3 +. 1.;;

val n4 : float = 281474976710657.

(n1 +. n4) -. n1 ;;

  • : float = 281474976710656. <----- n3 !

You are just witnessing floating point arithmetic precision errors.

@vicuna
Copy link
Author

vicuna commented Apr 8, 2015

Comment author: @alainfrisch

An often recommended introduction paper: "What Every Computer Scientist Should Know About Floating-Point Arithmetic".

http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant