Re: Fortran & unpack         


Author: Julien K.
Date: Jan 29, 2008 10:45

On 29-01-2008, Paul Gaborit wrote:
>
> À (at) Tue, 29 Jan 2008 15:18:15 +0100,
> "Julien K." wherever.you.want.com> écrivait (wrote):
>> [...]
>> $ perl -e 'print unpack("f",(pack("f",999.99))) ;'
>> 999.989990234375
>>
>> $ perl -e 'print sprintf("%%.4f",unpack("f",(pack("f",999.99)))) ;'
>> 999.9900
>>
>> Comment puis-je faire pour récupérer 999.99, valeur utilisée dans des
>> tests? Utiliser sprintf résoud le problème mais ça ne me semble pas /propre/.
>
> À mon avis, vous feriez mieux de travailler en DOUBLE plutôt qu'en
> FLOAT. La quasi totalité des processeurs modernes ne savent plus
> utiliser les floats (ils font leurs calculs en double et filtrent au
> dernier moment pour simuler les floats). Il n'y a que lorsqu'on est
> très très contraint en place mémoire qu'on utilise les floats mais
> c'est quand même très rare.

Dans le code Fortran? Oh je vais pas chercher à modifier cette masse
informe (avec des variables de 6 caractères max!) même si j'ai les sources
je risquerais de faire une connerie.

Je retiens toutefois la proposition pour un futur module de calcul.
> Bon, ceci étant dit, vous n'avez peut-être pas le choix...

L'autre alternative est de lire une sortie ASCII du code; je fixe
arbitrairement le format de sortie donc ça revient à peu-près au même que de
fixer l'arrondi du binaire (sauf que c'est plus lent à lire).
> Le problème constaté est tout fait normal et n'a rien à voir avec Perl
> C'est juste que la valeur stockée par un float ne peut pas être tout pile
> 999.99 donc si on l'affiche avec trop de précision on voit les derniers
> bits erronés.

Oui, ça je sais, je cherchais un moyen de limiter l'affectation des
variables à la partie codée (8 octets) du float (et pas me trimbaler le
bourrage de la mantisse).
> La solution du sprintf est pas mal pour arrondir mais le .4f est
> arbitraire (pourquoi 4 décimales après la virgule,

C'est la première qui marche ;-)
> et si la valeur vaut 1e-5 ou 1e20...). Je propose donc d'utiliser une
> même limite arbitraire mais ne dépendant pas de l'ordre de la valeur :
>
> perl -e 'print sprintf("%%g", unpack("f",(pack("f",999.99)))), "\n" ;'

Oui c'est effectivement mieux mais ça implique toujours de passer par une
chaîne de caractères pour arriver à un float... Enfin vu le temps
d'exécution c'est négligeable.

Merci pour ta réponse.

Julien
diggit! del.icio.us! reddit!