Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Nombre en virgule flottante

6 réponses
Avatar
kurtz le pirate
Bonjour,

Je ne sais pas si c'est les fêtes de fin d'année, mais ce ng est bien
vide :(


Bon, le but est de récupérer des nombres dans un fichier texte.
J'en suis la :

open(SRCFILE,"<$working_file") || die("Impossible d'ouvrir le fichier\n");
foreach my $line (<SRCFILE>) {
if (my @AllFloats = ( $line =~ /([-+]?([0-9]*\.[0-9]+|[0-9]+))/g) ) {
print $line;
foreach my $thisFloat (@AllFloats) {
print " > $thisFloat\n";
}
print "\n\n";
}
}
close(SRCFILE);

Ca fonctionne à peu prés bien. J'ai des résultats de ce type :

La ligne "source"
[0.9 p_micro1 rotate 90*y]
Le résulat :
> 0.9
> 0.9
> 1
> 1
> 90
> 90

Premièrement, je ne comprends pas pourquoi les valeurs sont en doubles ?
Le foreach est tout bête :(
Je dois faire une erreur quelque part. Vous voyez ou ?

Deuxièmement, et la c'est plus compliqué car c'est la regexp qui ne
fonctionne pas correctement. la valeur trouvée "1" vient de "p_micro1".
Bien sûr, c'est un nombre, mais il fait parti du nom d'une variable.
La je n'ai aucune piste pour résoudre ce cas.

Une idée ?


Le but final est de mettre en forme tout les nombres trouvés du genre :
.1 deviendra 0.100 par exemple
1 deviendra 1.000
-.5356854 deviendra -0.5356854


je n'en suis pas encore la... a moins qu'il existe déja un module qui
fait ça ?


Merci d'avance et bonnes fêtes.

--
kurtz le pirate
compagnie de la banquise

6 réponses

Avatar
Marc SCHAEFER
kurtz le pirate wrote:
open(SRCFILE,"<$working_file") || die("Impossible d'ouvrir le fichiern");

J'ai préféré réécrire, et sur le fichier de test
$ cat un_test
[0.9 p_micro1 rotate 90*y]
[-0.9 p_micro1 rotate 90*y]
[-0.9 p_micro1 rotate 90*y]
[+0.9 p_micro1 rotate 90*y]
[-.536854 p_micro1 rotate 90*y]
la sortie semble pas mal:
$ ./a.pl
0.900
-0.900
-0.900
0.900
-0.537

$ cat a.pl
! /usr/bin/perl
use strict;
use warnings;
my $working_file = "un_test";
open(SRCFILE, '<', $working_file)
or die("Impossible d'ouvrir le fichier: " . $working_file . "n");
my @all_floats;
while (my $line = <SRCFILE>) {
chomp $line;
if ($line =~ /^[([+-]{0,1}d{0,1}+(.d+)}{0,1})/) {
push(@all_floats, $1);
}
}
close(SRCFILE); # err. ign.
map { printf "> %.3fn", $_ } @all_floats;
Avatar
kurtz le pirate
On 29/12/2019 12:47, Marc SCHAEFER wrote:
kurtz le pirate wrote:
open(SRCFILE,"<$working_file") || die("Impossible d'ouvrir le fichiern");

J'ai préféré réécrire, et sur le fichier de test
...

merci pour ta réponse... mais cela ne semble pas fonctionner :(
les lignes ne commencent pas forcément par un nombre $line =~ /^....
si l'on prend cette ligne "source" :
object { sheet(Cl_SI_D65*2000)scale <100,.1,100> translate 0.9*y}
j'obtiens :
65
65
2000
2000
100
100
.1
.1
100
100
0.9
0.9

si l'on fait abstraction des valeurs en double, on a bien les 6 nombres.
le "65" n'est pas bon car il fait parti du nom Cl_SI_D65.
je n'ai aucun résultat avec ton exemple sur mon fichier.
d'ailleur, même avec ta sortie sur le même exemple :
[0.9 p_micro1 rotate 90*y]
tu ne récupères que le premier nombre 0.9 et pas le deuxième 90.
--
kurtz le pirate
compagnie de la banquise
Avatar
Marc SCHAEFER
kurtz le pirate wrote:
merci pour ta réponse... mais cela ne semble pas fonctionner :(

Elle fonctionne sur mon exemple. Tu n'avais pas expliqué que tu veux
les nombres, mais pas les nombres faisant partie d'identifiants, et
qu'il y a plusieurs nombres par ligne.
Dans ce cas, voici quelques pistes:
- utiliser le modificateur /ge, du style:
$line =~ s/.../push(@..., $1)/ge;
- utiliser un pré-remplacement supprimant tous les identificateurs
Avatar
kurtz le pirate
On 29/12/2019 16:24, Marc SCHAEFER wrote:
kurtz le pirate wrote:
merci pour ta réponse... mais cela ne semble pas fonctionner :(

Elle fonctionne sur mon exemple. Tu n'avais pas expliqué que tu veux
les nombres, mais pas les nombres faisant partie d'identifiants, et
qu'il y a plusieurs nombres par ligne.
Dans ce cas, voici quelques pistes:
- utiliser le modificateur /ge, du style:
$line =~ s/.../push(@..., $1)/ge;
- utiliser un pré-remplacement supprimant tous les identificateurs

merci. j'avance un peu :
foreach my $line (<SRCFILE>) {
if ( $line =~ /([-+]?([0-9]*.[0-9]+|[0-9]+))/) {
print $line;
$line =~ s/([-+]?([0-9]*.[0-9]+|[0-9]+))/sprintf ("%.3f",$1)/ge;
print $line;
print "nn";
}
}
qui me donne :
source :
object { sheet(Cl_SI_D65*2000)scale <100,.1,100> translate 0.9*y}
resultat :
object { sheet(Cl_SI_D65.000*2000.000)scale <100.000,0.100,100.000>
translate 0.900*y}
encore le problème des identifants : Cl_SI_D65.
--
kurtz le pirate
compagnie de la banquise
Avatar
kurtz le pirate
On 29/12/2019 16:49, kurtz le pirate wrote:
encore le problème des identifants : Cl_SI_D65.

que j'ai à peu près résolut comme ça :
$line =~ s/([-+]?([0-9]*.[0-9]+|[0-9]+))/fnFormat($1)/ge;
et la fonction :
sub fnFormat {
my $n = shift;
($n =~ /./ ? sprintf ("%.3f",$n) : $n)
}
j'avance.
--
kurtz le pirate
compagnie de la banquise
Avatar
Nicolas George
kurtz le pirate , dans le message
<5e088e79$0$20339$, a écrit :
Premièrement, je ne comprends pas pourquoi les valeurs sont en doubles ?

Tu as deux paires de parenthèses, donc deux captures par nombre reconnu.
Le foreach est tout bête :(
Je dois faire une erreur quelque part. Vous voyez ou ?
Deuxièmement, et la c'est plus compliqué car c'est la regexp qui ne
fonctionne pas correctement. la valeur trouvée "1" vient de "p_micro1".
Bien sûr, c'est un nombre, mais il fait parti du nom d'une variable.
La je n'ai aucune piste pour résoudre ce cas.

Regarde du côté de b.