PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Forums Hébergement > Forum Serveur - Sécurité et techniques > fr.comp.os.unix > Arrondis
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
fr.comp.os.unix Système UNIX.

Arrondis

Réponse
 
LinkBack Outils de la discussion
Vieux 20/03/2007, 17h19   #1
Gamotte
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Arrondis

Bonjour,

je voudrais remplacer un fichier par le même fichier
dans lequel tous les nombres ont été arrondis à 3
chiffres après la virgule, l'arrondi étant vers le haut
ou le bas selon celui qui est le plus proche.
Le fichier contient du texte et des nombres disséminés
dans le texte. Je ne peux donc pas utiliser un tableur
et recherche donc une solution du type rechercher/remplacer.

Merci

--
Yves

  Réponse avec citation
Vieux 20/03/2007, 18h21   #2
Stephane Chazelas
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Arrondis

2007-03-20, 09:19(-07), Gamotte:
[...]
> je voudrais remplacer un fichier par le même fichier
> dans lequel tous les nombres ont été arrondis à 3
> chiffres après la virgule, l'arrondi étant vers le haut
> ou le bas selon celui qui est le plus proche.
> Le fichier contient du texte et des nombres disséminés
> dans le texte. Je ne peux donc pas utiliser un tableur
> et recherche donc une solution du type rechercher/remplacer.

[...]

perl -pi -e 's/\d*\.\d{4,}/sprintf("%.3f",$&)/eg' fichier

--
Stéphane
  Réponse avec citation
Vieux 20/03/2007, 18h37   #3
Alain Ketterlin
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Arrondis

"Gamotte" <gamotte@hotmail.com> writes:

> je voudrais remplacer un fichier par le même fichier dans lequel
> tous les nombres ont été arrondis à 3 chiffres après la virgule,
> l'arrondi étant vers le haut ou le bas selon celui qui est le plus
> proche. Le fichier contient du texte et des nombres disséminés dans
> le texte. Je ne peux donc pas utiliser un tableur et recherche donc
> une solution du type rechercher/remplacer.


Je suis sur que tu auras plein de réponse Perl etc. Je te propose un
petit analyseur lexical à la place (c'est printf() qui fait l'arrondi,
mais tu pourrais passer à round()) :

-- rond.lex ------------------------------------------------
%{
#include <stdlib.h>
"include <stdio.h>
%}
%option nounput
%option main
%%
[0-9]+\.[0-9]+ {printf("%.3lf",atof(yytext));}
%%
------------------------------------------------------------

Puis :

lex -orond.c rond.lex && cc rond.c -o rond

(ou flex ... et gcc). Et roulez jeunesse.

-- Alain.
  Réponse avec citation
Vieux 21/03/2007, 11h26   #4
Gamotte
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Arrondis

Merci à tous les deux.
Je n'avais pas pensé à lex, c'est une bonne idée.
Concernant la réponse de Stéphane, c'est le 'e'
de 'eg' qui indique qu'il faut interpréter la chaine de
remplacement comme une expression, c'est bien
ça ?

  Réponse avec citation
Vieux 21/03/2007, 15h08   #5
Stephane Chazelas
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Arrondis

2007-03-21, 03:26(-07), Gamotte:
> Merci à tous les deux.
> Je n'avais pas pensé à lex, c'est une bonne idée.
> Concernant la réponse de Stéphane, c'est le 'e'
> de 'eg' qui indique qu'il faut interpréter la chaine de
> remplacement comme une expression, c'est bien
> ça ?


Oui, voir perldoc perlop

--
Stéphane
  Réponse avec citation
Vieux 21/03/2007, 15h30   #6
Gamotte
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Arrondis

merci

  Réponse avec citation
Vieux 25/03/2007, 23h41   #7
Vincent Lefevre
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Arrondis

Dans l'article <slrnf00610.849.stephane.chazelas@spam.is.invalid> ,
Stephane Chazelas <cette.adresse@est.invalid> écrit:

> 2007-03-20, 09:19(-07), Gamotte:
> [...]
> > je voudrais remplacer un fichier par le même fichier
> > dans lequel tous les nombres ont été arrondis à 3
> > chiffres après la virgule, l'arrondi étant vers le haut
> > ou le bas selon celui qui est le plus proche.
> > Le fichier contient du texte et des nombres disséminés
> > dans le texte. Je ne peux donc pas utiliser un tableur
> > et recherche donc une solution du type rechercher/remplacer.

> [...]


> perl -pi -e 's/\d*\.\d{4,}/sprintf("%.3f",$&)/eg' fichier


Mauvaise solution (ou excellente solution, suivant le cas).

En faisant ça, tu vas dire à Perl de d'abord convertir une chaîne en
nombre double précision IEEE 754 et provoquer une erreur d'arrondi,
qui pourra donner un résultat différent. Par exemple:

echo 1.01250000000000001 | perl -pe 's/\d*\.\d{4,}/sprintf("%.3f",$&)/eg' -

donne "1.012" au lieu de "1.013". La solution de ne travailler que
sur la chaîne en base 10 est la bonne.

Maintenant, si les nombres stockés dans le fichier sont censés être
des représentations de nombres en double précision (comme ce qui
peut se faire avec le type double de XML, cf XML Schema Part 2),
alors au contraire, c'est la bonne solution.

--
Vincent Lefèvre <vincent@vinc17.org> - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)
  Réponse avec citation
Vieux 26/03/2007, 00h09   #8
Vincent Lefevre
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Arrondis

Dans l'article <87aby7yfxr.fsf@dpt-info.u-strasbg.fr>,
Alain Ketterlin <alain@dpt-info.u-strasbg.fr> écrit:

> "Gamotte" <gamotte@hotmail.com> writes:


> > je voudrais remplacer un fichier par le même fichier dans lequel
> > tous les nombres ont été arrondis à 3 chiffres après la virgule,
> > l'arrondi étant vers le haut ou le bas selon celui qui est le plus
> > proche. Le fichier contient du texte et des nombres disséminés dans
> > le texte. Je ne peux donc pas utiliser un tableur et recherche donc
> > une solution du type rechercher/remplacer.


> Je suis sur que tu auras plein de réponse Perl etc. Je te propose un
> petit analyseur lexical à la place (c'est printf() qui fait l'arrondi,
> mais tu pourrais passer à round()) :


> -- rond.lex ------------------------------------------------
> %{
> #include <stdlib.h>
> "include <stdio.h>
> %}
> %option nounput
> %option main
> %%
> [0-9]+\.[0-9]+ {printf("%.3lf",atof(yytext));}
> %%
> ------------------------------------------------------------


Cf ma réponse à Stéphane. Ta solution a le même problème. La solution
générale (y compris pour un fichier avec des nombres à plage et à
précision arbitraire) la moins complexe est probablement d'utiliser
quelques expressions régulières pour traiter tous les cas possibles
et faire les transformations. Si la plage des nombres est restreinte
(à déterminer...), alors la solution suivante peut convenir:

perl -pe \
's/(\d*\.\d{3})(\d)\d*/$2 < 5 ? $1 : sprintf("%.3f", $1 + 0.001)/eg'

(il s'agit d'un arrondi "away from zero", comme ce qui se fait souvent
en base 10).

--
Vincent Lefèvre <vincent@vinc17.org> - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)
  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 01h55.


Édité par : vBulletin® version 3.7.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,16640 seconds with 16 queries