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

conversion string->decimal

40 réponses
Avatar
Olivier Berquin
Bonjour tout le monde,

C'est ma première intervention ici.
J'ai recherché dans les anciens messages et n'ait pas trouvé de
solution...

J'ai un formulaire dans lequel l'utilisateur doit encoder un montant
(decimal).
Mon input est au format texte.
Comment puis-je être certain d'avoir un type decimal?

j'ai fait ceci, mais ça me paraît un peu tiré par les cheveux:
$val1 = $montant + 0.001;
$val2 = $val1 - 0.001;
if ($val2 == 0)
{
// Ce n'est pas un nombre...
}

Merci.

Oli.

10 réponses

1 2 3 4
Avatar
Olivier Miakinen
[ Je remets le titre d'origine car on revient à la question initiale ]

Voici ma fonction:
function my_is_numeric($valeur)
{
$is_num = preg_match('/^[+-]?[0-9]*[,.]*[0-9]*$/', $valeur);
return ($is_num);
}


Et voici un petit tableau avec quelques exemples de valeurs acceptées
ou refusées (en rouge):
<http://olivier.berquin.free.fr/job/test_montant>


Voici un autre exemple de valeur acceptée que je ne vois pas dans ton
tableau : "8,.,.,.,.3".

Auriez-vous la gentillesse de me dire si c'est assez rigoureux sans
être trop rigide?


Tout d'abord, comme pour le + et ainsi que l'a déjà signalé P'tit
Marcel, il est inutile d'échapper le . dans une classe de caractères.

Ensuite, et surtout, tu ne nous as pas dit quel traitement tu faisais
sur la valeur une fois qu'elle a été acceptée. J'avais supposé qu'elle
allait servir à faire des calculs, et qu'au final elle devait être
conforme à la syntaxe des flottants en PHP (donc pas d'espace ni de
virgule dedans). Or tu ne fais apparemment aucune transformation pour
remplacer une virgule par un point décimal, et P'tit Marcel semble
regretter que ta dernière proposition n'ait plus de séparateurs de
milliers...


Si vraiment tu veux faire des calculs avec ces nombres, alors il me
semble qu'il faudrait :
1) définir d'abord clairement la syntaxe que tu veux accepter (et la
*documenter* pour les utilisateurs qui devront faire la saisie) ;
2) écrire le code permettant de contrôler cette syntaxe. Il est possible
d'être un peu plus souple en éliminant silencieusement certains
caractères non prévus, en particulier les espaces avant et après ;
3) si la syntaxe en question n'est pas compatible avec celle de PHP,
écrire le code permettant la traduction dans un sens, mais aussi
dans l'autre sens, afin de présenter à l'utilisateur une syntaxe
qui corresponde, à l'affichage aussi, à ce que tu as documenté.

Et attention de ne pas placer la charrue avant les b½ufs, c'est-à-dire
se préoccuper des points (2) et (3) avant d'avoir complètement résolu
le (1).

Avatar
Olivier Miakinen

Hé bien je ne suis *vraiment* pas d'accord avec ton *vrai* désaccord ;-)


:-D

Un masque est déjà assez difficile à lire, autant ne pas le borner par
des caractères imposants par la taille et qui cachent l'essentiel, à
savoir les classes de caractères [], les sous-masques () et autres
assertions ?< ?=.


Ce n'est pas faux. D'ailleurs je n'ai pas très envie à priori d'utiliser
[] et (). En revanche, {} me semblerait un assez bon choix à la place de
// (quand aucun des deux n'est dans l'expression, bien sûr).

Par ailleurs, on parle d'un délimiteur et les
délimiteurs de loin les plus fréquents en programmation sont les
guillemets simples ou doubles. L'antiguillemet simple ` est une
approximation proche de ces délimiteurs habituels. La preuve que c'est
un bon choix, c'est que c'est le caractère que j'utilise dans les
masques preg_*** !


Je n'ai pas dit non plus que l'accent grave ` était un mauvais
délimiteur, hein ! Sauf bien sûr s'il fait partie de l'expression
rationnelle.

Le vrai scandale est qu'il soit nécessaire d'employer un délimiteur. Le
premier paramètre des fonctions preg_** correspond en réalité à deux
propriétés qui n'ont rien à voir entre elles: d'une part le masque et
d'autre part les modificateurs. Dans tout langage digne de ce nom, ces
propriétés seraient transmises dans deux paramètres distincts.


Alors là je ne peux qu'approuver sans réserve.

Cordialement,
--
Olivier

Avatar
Olivier Berquin
Ensuite, et surtout, tu ne nous as pas dit quel traitement tu faisais
sur la valeur une fois qu'elle a été acceptée.


Oups.
Quel c...
En gros (en très gros, même), je fais une espèce d'intranet de
"gestion" des jobs au sein de notre entreprise. Je travaille en PHP
avec des tables en MySQL.
Concernant le "problème" de vérification d'un montant: il s'agit d'un
petit formulaire pour encoder diverses données sur une facture (par
rapport à un job).
L'utilisateur encode donc son montant dans un champ "text".
J'écris ensuite ces données dans ma db.

Merci pour la remarque "8,.,.,.,.3"
J'ai modifié ma fonction comme suit:
function my_is_numeric($valeur)
{
$is_num = preg_match('/^[+-]*[0-9]*[,.]?[0-9]*$/', $valeur);
return ($is_num);
}


Oli.

Avatar
P'tit Marcel
Alors là je ne peux qu'approuver sans réserve.


Ouf, je n'aurais pas à ma castagner avec OM !

--
P'tit Marcel

Avatar
P'tit Marcel
Concernant le "problème" de vérification d'un montant: il s'agit d'un
petit formulaire pour encoder diverses données sur une facture (par
rapport à un job).
L'utilisateur encode donc son montant dans un champ "text".
J'écris ensuite ces données dans ma db.


ok donc les séparateurs de milliers ne sont pas les bienvenus.

J'ai modifié ma fonction comme suit:
function my_is_numeric($valeur)
{
$is_num = preg_match('/^[+-]*[0-9]*[,.]?[0-9]*$/', $valeur);
____________________________________^


AMHA, il reste une erreur : remplace le premier * par un ?
tel que tu l'as écrit, la fonction autoriserait la saisie de
++----++34.3 par exemple

Par ailleurs, ta fonction acceptera une absence de saisie (chaîne vide)
voire la saisie d'un signe tout seul (+ - . ,) ce qui n'est peut être
pas ce que tu veux.

NB: après une classe de caractère []
* veut dire "un nombre quelconque de fois, ou pas du tout"
? veut dire "une fois, ou pas du tout"
+ veut dire "un nombre quelconque de fois"


eça
--
P'tit Marcel
stats sur les forums modérés http://www.centrale-lyon.org/ng/

Avatar
Olivier Miakinen
Ensuite, et surtout, tu ne nous as pas dit quel traitement tu faisais
sur la valeur une fois qu'elle a été acceptée.


En gros (en très gros, même), je fais une espèce d'intranet de
"gestion" des jobs au sein de notre entreprise. Je travaille en PHP
avec des tables en MySQL.
Concernant le "problème" de vérification d'un montant: il s'agit d'un
petit formulaire pour encoder diverses données sur une facture (par
rapport à un job).


Mais cette donnée particulière, elle sert juste à l'affichage (auquel
cas "3,99" sera probablement mieux compris en français que "3.99") ou
bien elle sert à des calculs (auquel cas "3,99" risque de se transformer
en "3") ? Quand je te demandais quel traitement tu faisais sur cette
valeur, je voulais dire « quel code PHP pour transformer la chaîne en
nombre " ?

En outre, si tu acceptes aussi bien la virgule que le point en entrée,
est-ce que tu gardes ça à l'affichage, d'où risque de confusion ?

J'ai modifié ma fonction comme suit:
function my_is_numeric($valeur)
{
$is_num = preg_match('/^[+-]*[0-9]*[,.]?[0-9]*$/', $valeur);
return ($is_num);
}


Mêmes questions, donc.


Avatar
Olivier Miakinen

ok donc les séparateurs de milliers ne sont pas les bienvenus.


Ouf, je n'aurai pas à me castagner avec PM !

Avatar
Olivier Berquin
Merci pour tous vos éclaircissements.

Concernant la chaîne vide, ce n'est pas trop un problème.

Oli.

NB On a, pour une fois, évité une "guerre de codes" ;-)
Avatar
P'tit Marcel
Mes remarques à 2 roupies :
- contrairement aux premières versions, ce masque ne permet pas de
séparateurs de milliers (sauf pour les nombres entiers inférieurs à un
million)


Une remarque en passant : il est faux de croire que toutes les cultures
séparent les chiffres en milliers. Par exemple, les indiens (d'Inde)
utilisent parfois des séparateurs tous les deux chiffres :

cent mille = 1 "Lakh" = 1,00,000
un milliard = 1 "Arab" = 1,00,00,00,000

Les chinois utilisent parfois des séparateurs tous les 4 chiffres
(ça doit être vrai car je l'ai lu sur internet).

Par ailleurs, le Révéré SI (Système International d'unité) précise
que le séparateur des milliers Ne Doit Pas Être un . ou une ,
Mais Seulement Un Espace
(voir http://www.bipm.org/utils/common/pdf/si_brochure_8_fr.pdf page 48)

Bon, j'admets que ces précisions sont d'un usage limité dans nos
régions, mais ça vous donnera peut-être un succès d'estime devant la
machine à café :-)

--
P'tit Marcel
stats sur les forums modérés http://www.centrale-lyon.org/ng/

Avatar
Olivier Miakinen

Une remarque en passant : il est faux de croire que toutes les cultures
séparent les chiffres en milliers. Par exemple, les indiens (d'Inde)
utilisent parfois des séparateurs tous les deux chiffres :

cent mille = 1 "Lakh" = 1,00,000
un milliard = 1 "Arab" = 1,00,00,00,000


Oui, les Pakistanais aussi.

Les chinois utilisent parfois des séparateurs tous les 4 chiffres
(ça doit être vrai car je l'ai lu sur internet).


C'est vrai, mais je ne suis pas sûr que cela s'applique aux chiffres
(que nous nommons) arabes.

Par ailleurs, le Révéré SI (Système International d'unité) précise
que le séparateur des milliers Ne Doit Pas Être un . ou une ,
Mais Seulement Un Espace


Absolument. J'irais même jusqu'à préciser « une » espace « insécable ».

(voir http://www.bipm.org/utils/common/pdf/si_brochure_8_fr.pdf page 48)


Merci pour le lien.

1 2 3 4