Navigation Menu

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

int_of_float and ocamlopt #8018

Closed
vicuna opened this issue Feb 18, 2003 · 5 comments
Closed

int_of_float and ocamlopt #8018

vicuna opened this issue Feb 18, 2003 · 5 comments
Labels

Comments

@vicuna
Copy link

vicuna commented Feb 18, 2003

Original bug ID: 1546
Reporter: administrator
Status: closed
Resolution: not a bug
Priority: normal
Severity: minor
Category: ~DO NOT USE (was: OCaml general)

Bug description

Full_Name: erwan jahier
Version: 3.06
OS: linux
Submission from: ossau.imag.fr (129.88.43.4)

let _ =
print_int (int_of_float (4.1 *. 10.)) ;
print_string "\n";
flush stdout

This chunck of code prints 40 if compiled with ocamlopt and 41. with ocamlc...

uname -a
Linux ecrins 2.4.20-verimag #1 SMP Fri Jan 24 10:16:46 CET 2003 i686 unknown

ocamlopt -v
The Objective Caml native-code compiler, version 3.06
Standard library directory: /home/jahier/lib/ocaml

ocamlopt bug.ml -o bug-nc
./bug-nc
40

ocamlc bug.ml -o bug-bc
./bug-bc

41

@vicuna
Copy link
Author

vicuna commented Feb 18, 2003

Comment author: administrator

let _ =
print_int (int_of_float (4.1 *. 10.)) ;
print_string "\n";
flush stdout

This chunck of code prints 40 if compiled with ocamlopt and 41. with
ocamlc...

Le Pentium est une architecture un peu spéciale: les calculs flottants
sont faits en précision étendue (80 bits), la conversion en précision
normale (64 bits) étant faite au moment du stockage en mémoire.

Comme ni 4.1 ni 10.0 ne sont représentables exactement en flottants,
le calcul 4.1 * 10.0 donne le résultat intermédiaire
40.99999999999999644... en précision étendue, qui est arrondi à 41.000...
lorsque ce résultat est stocké en mémoire.

ocamlc stocke tous les résultats intermédiaires en mémoire (sur 64 bits).
ocamlopt en garde le plus possible dans les registres flottants (sur 80 bits).
C'est en particulier le cas du résultat intermédiaire 4.1 * 10.0
dans le calcul int_of_float (4.1 *. 10.0).

Les joies de l'arithmétique flottante.

  • Xavier Leroy

@vicuna
Copy link
Author

vicuna commented Feb 18, 2003

Comment author: administrator

On Tue, 18 Feb 2003, Xavier Leroy wrote:

Le Pentium est une architecture un peu spéciale: les calculs flottants
sont faits en précision étendue (80 bits), la conversion en précision
normale (64 bits) étant faite au moment du stockage en mémoire.

Comme ni 4.1 ni 10.0 ne sont représentables exactement en flottants,
le calcul 4.1 * 10.0 donne le résultat intermédiaire
40.99999999999999644... en précision étendue, qui est arrondi à 41.000...
lorsque ce résultat est stocké en mémoire.

Euh... Tu veux dire arrondi a 40.O j'imagine.
Je comprend maintenant pourquoi ca ne le faisait pas avec 4.2 !

ocamlc stocke tous les résultats intermédiaires en mémoire (sur 64 bits).
ocamlopt en garde le plus possible dans les registres flottants (sur 80 bits).
C'est en particulier le cas du résultat intermédiaire 4.1 * 10.0
dans le calcul int_of_float (4.1 *. 10.0).

Les joies de l'arithmétique flottante.

Est-ce à dire que ca n'est pas un bug ?

Je suis pret à l'admettre, après tout, les flottants ne sont pas des
réels, il n'y a donc rien à en attendre mathèmatiquement.

Mais dans ce cas,

let f = 4.1 *. 10. in
int_of_float f

... ne devrait pas donner le bon résultat à savoir, 41.

--
R1.

@vicuna
Copy link
Author

vicuna commented Feb 18, 2003

Comment author: administrator

Comme ni 4.1 ni 10.0 ne sont représentables exactement en flottants,
le calcul 4.1 * 10.0 donne le résultat intermédiaire
40.99999999999999644... en précision étendue, qui est arrondi à 41.000...
lorsque ce résultat est stocké en mémoire.

Euh... Tu veux dire arrondi a 40.O j'imagine.

Non, non: la conversion précision étendue -> précision mémoire est
bien un arrondi. (Pas à l'entier le plus proche: au flottant en
précision normale le plus proche.) C'est int_of_float qui tronque.

Est-ce à dire que ca n'est pas un bug ?

int_of_float est par définition une fonction discontinue, et donc mal
définie sur les flottants aux voisinages des entiers exacts. Bien
sûr, ça m'embête de voir apparaître des résultats étranges liés à
l'utilisation de la précision étendue dans ocamlopt, mais c'est
difficile de faire autrement sur le Pentium sans perdre beaucoup en
efficacité. Heureusement, tous les autres processeurs du marché
calculent en précision normale!

Mais dans ce cas,

let f = 4.1 *. 10. in
int_of_float f

... ne devrait pas donner le bon résultat à savoir, 41.

Ben si, parce que là le "let" force un stockage en mémoire du résultat
intermédiaire, et donc un arrondi!

  • Xavier Leroy

@vicuna
Copy link
Author

vicuna commented Feb 18, 2003

Comment author: administrator

On Tue, 18 Feb 2003, Xavier Leroy wrote:

Mais dans ce cas,

let f = 4.1 *. 10. in
int_of_float f

... ne devrait pas donner le bon résultat à savoir, 41.

Ben si, parce que là le "let" force un stockage en mémoire du résultat
intermédiaire, et donc un arrondi!

J'avais compris.

Je voulais simplement dire que le fait les résultats soient differents
selon comment on écrit les choses (avec un let ou pas) est un bug.

En fait, int_of_float ne devrait pas tronquer, mais prendre l'entier le
plus proche. Ceci rendrait peut-etre moins efficace cette fonction, mais
ne changerait pour les autres operations sur les flottants.

Merci pour toutes ces précisions en tout cas.

R1.

@vicuna
Copy link
Author

vicuna commented Feb 18, 2003

Comment author: administrator

J'avais compris.

Je voulais simplement dire que le fait les résultats soient differents
selon comment on écrit les choses (avec un let ou pas) est un bug.

En fait, int_of_float ne devrait pas tronquer, mais prendre l'entier le
plus proche. Ceci rendrait peut-etre moins efficace cette fonction, mais
ne changerait pour les autres operations sur les flottants.

Mon grain de sel.

Et non, a priori on obtiendra des différences de comportement du même
genre au voisinage des xxx.5, à mi-chemin entre deux entiers.

Il est vrai que c'est sans doute moins perturbant.

Sans garanties, parce que les flottants...

--
R1.

--Luc

@vicuna vicuna closed this as completed Feb 23, 2003
@vicuna vicuna added the bug label Mar 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant