String vers double qui pose problème

Tank01 Messages postés 106 Date d'inscription lundi 4 août 2003 Statut Membre Dernière intervention 10 novembre 2006 - 24 mai 2006 à 17:14
jponselle Messages postés 4 Date d'inscription mercredi 15 novembre 2006 Statut Membre Dernière intervention 22 mai 2012 - 14 nov. 2010 à 16:35
Bonjour,

Soit une string sous cette forme :

xxxx.xx

x étant obligatoirement un chiffre allant de 0 à 9

comment transformer cette string en un entier arrondi, ou au moins en un réel, et l'arrondir par la suite ( le StrToFloat me cause aparemment une exception dans mon programme)

Vous souhaitant une agrébale fin d'après-midi ,merci à tous

----( | TanK | )---- 
A voir également:

15 réponses

japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
24 mai 2006 à 17:44
Salut,



Tout ça est très basique. Pourquoi ne regardes-tu pas l'aide de Delphi ?
Par exemple, tu mets StrToFloat en surbrillance et tu presses la touche F1.

Néanmoins, si ça peut t'éclairer, penche-toi sur ces lignes de code :

procedure TForm1.Button1Click(Sender: TObject);
var
  MyString: string;
  MyFloat: Real;
  MyInteger: Integer;
begin  MyString :'1789,50';  // <- separateur virgule
  MyFloat := StrToFloat(MyString);
  ShowMessage(FloatToStr(MyFloat));  MyFloat :1789.50;     // <- separateur point
  ShowMessage(FloatToStr(MyFloat));
  MyInteger := Round(StrToFloat(MyString));
  ShowMessage(IntToStr(MyInteger));
  MyInteger := Trunc(StrToFloat(MyString));
  ShowMessage(IntToStr(MyInteger));
end;

Bonne prog'
0
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
24 mai 2006 à 18:03
Bonjour,

Un exemple:

var
   R : real;
   I,Code : Integer;

val( '1254.63' , R , Code ) ;
I : = round(R);
0
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
24 mai 2006 à 18:38
salut,

attention au séparateur décimal avec strtofloat il prend celui défini
dans les variables régionales : en france c'est une virgule pas un point


@+

jlen
0
Tank01 Messages postés 106 Date d'inscription lundi 4 août 2003 Statut Membre Dernière intervention 10 novembre 2006
26 mai 2006 à 08:34
Bien,bien bien, mais comment faire dans mon cas,si ce séparateur est un point et non une virgule ?

merci encore

----( | TanK | )---- 
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Tank01 Messages postés 106 Date d'inscription lundi 4 août 2003 Statut Membre Dernière intervention 10 novembre 2006
26 mai 2006 à 08:42
Oupssss,veuillez m'excusez, je crois que le matin ne me réussi pas et que je devrais plutot réfléchir aavnt d'agir, je vais tout simplement coder une fonction avec Pos qui recherchera le point et enlevera tout ce qu'il y a après ,puis j'arrondirais cela et stockerais dans un entier. Encore désolé pour ma question aussi bête !

Bonne journée

----( | TanK | )---- 
0
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
26 mai 2006 à 10:38
function StrToXtd(Chaine,DecSep :string):extended;
var L,K,i: integer;
    R:extended;
begin
  R:=0;
  L:=Length(Chaine);
  K:=Pos(DecSep,Chaine);
  For i:=1 to L do
  if Chaine[i] in ['0'..'9']
  then R:=R*10.0 + StrToInt(Chaine[i]);

  if K > 0 then R:=R/IntPower(10,(L-K));
  if Pos('-',Chaine) > 0 then R:=R*(-1);

  Result:= R;
end;
0
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
26 mai 2006 à 14:21
> DeltaFX


Ta fonction donne un résultat incorrect si un usager saisit un point quand le séparateur décimal par défini par défaut est la virgule, comme c'est la norme en France par exemple.

Ma chtit' fonction :

function StrToXtended(S: string): Extended;
const
  DecSep = [',', '.'];
var
  i: Integer;
begin
  for i := 1 to Length(S) do
    if S[i] in DecSep then
      S := StringReplace(S, S[i], DecimalSeparator, []);
  Result := StrToFloat(S);
end;

Bonne prog'
0
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
26 mai 2006 à 14:42
Ce que j'ai dit précédemment est faux, j'avais mal testé ta fonction.


Il faut dire que le programmeur est obligé de passer en paramètre '.' ou ',' selon la configuration trouvée sur la machine utilisateur, ce qui complique et risque de provoquer des erreurs, la preuve...

Il vaut mieux une méthode qui tient compte de toutes les possibilités, non ?

Bonne prog'
0
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
26 mai 2006 à 17:23
J'ai compliqué inutilement en utilisant StringReplace()



Il vaut mieux faire :

function StrToXtended(S: string): Extended;
const
  DecSep = [',', '.'];
var
  i: Integer;
begin
  for i := 1 to Length(S) do
    if S[i] in DecSep then
      S[i] := DecimalSeparator;
  Result := StrToFloat(S);
end;

Bonne prog'
0
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
27 mai 2006 à 10:32
Japee, j'avais écrit cette fonction jadis justement pour contourner le StrToFloat, qui refusait de marcher alors que mes données était toujours bien claires. Remettre un StrToFloat dedans, beuhhhhhhhhhhhhhh........

Justement, je la trouvais assez flexible ma tite fonction, vu qu'elle me sert pour lire des données d'un port com, qui sont indépendante de la localisation du pc de l'utilisateur. Elle est incomplete en cela qu'elle ne traite pas l'ecriture scientifique

 En plus les "Normes" en France... Toutes mes calculatrices ont toujours eu le point comme séparateur decimal, et surtout, va expliquer à un appareil externe  que bien que la Norme NMEA definisse la virgule comme séparateur de champs, et le point comme séparateur décimal, on est en France...........
0
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
27 mai 2006 à 12:01
Finalement, je l'aime bien ta fonction, DeltaFX.


C'est du fait main et ça a l'air efficace.



Pour contourner le problème point/virgule, on peut toujours faire quelque chose dans le genre :

function StrToXtdRevisited(Chaine: string): Extended;
var
  L, K, i: Integer;
  R: Extended;
begin
  R := 0;
  L := Length(Chaine);
  K := Pos(',', Chaine);
  if K = 0 then
    K := Pos('.', Chaine);
  for i := 1 to L do
    if Chaine[i] in ['0'..'9']
      then R := R * 10.0 + StrToInt(Chaine[i]);
  if K > 0 then R := R / IntPower(10, (L - K));
  if Pos('-', Chaine) = 1 then R := R * (-1);
  Result:= R;
end;

Bonne prog'
0
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
27 mai 2006 à 21:47
Sauf en cas de format alako... anglosaxon... du genre 1,000,000.00, auquel cas, c'est le drame

Pour faire bien propre, il faudrait la surcharger, la bestiole.

Peut on faire un truc dans le genre

function StrToXtdRevisited(Chaine:string; Sep:String=','): Extended;
0
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
28 mai 2006 à 13:11
Tank01 semblant se désintéresser totalement de sa question, on va continuer entre nous, DeltaFX.

Donc j'ai essayé, on peut :

uses Math;



const
  DS_COMMA = 0;
  DS_DOT   = 1;



function StrToXtdRevisited(S: string; const DS: Byte = DS_COMMA): Extended;
var
  L, K, i: Integer;
begin
  Result := 0;
  L := Length(S);
  case DS of
    DS_COMMA: K := Pos(',', S);
    DS_DOT: K := Pos('.', S);
    else Exit;
  end;
  for i := 1 to L do
    if S[i] in ['0'..'9']
      then Result := Result * 10.0 + StrToInt(S[i]);
  if K > 0 then Result := Result / IntPower(10, (L - K));
  if Pos('-', S) = 1 then Result := Result * (-1);
end;



procedure TForm1.Button1Click(Sender: TObject);
begin { norme européenne latine }
  Edit2.Text := FloatToStr(StrToXtdRevisited(Edit1.Text, DS_COMMA));
  {
  on aurait pu faire, bien sûr :
  Edit2.Text := FloatToStr(StrToXtdRevisited(Edit1.Text));
  ou
  Edit2.Text := FloatToStr(StrToXtdRevisited(Edit1.Text, 0));
  }
end;



procedure TForm1.Button2Click(Sender: TObject);
begin { norme anglo-saxonne }
  Edit2.Text := FloatToStr(StrToXtdRevisited(Edit1.Text, DS_DOT));
end;



procedure TForm1.Button3Click(Sender: TObject);
var   { la valeur du paramètre passé est erronnée }
  N_IMPORTE_QUOI: Byte;
begin
  N_IMPORTE_QUOI := 9; // n'importe quoi...
  Edit2.Text := FloatToStr(StrToXtdRevisited(Edit1.Text, N_IMPORTE_QUOI));
end;


Voir pour information (in english, sorry) :

http://en.wikipedia.org/wiki/Decimal_separator

Bonne prog'

japee
0
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
28 mai 2006 à 19:15
Arf, pris d'un doute j'ai jeté un oeil a Srtofloat tel que décrit dans les source de delphi, qui me renvoie a TxtToFloat, qui est écrit...... en assembleur, donc j'ai rien capté :D

Merci pour le lien wiki, tres instructif, et surtout, maintenant c'est sur, JAMAIS j'écrirais de strtofloat pour une plateforme indienne, Oh non non non.....
0
jponselle Messages postés 4 Date d'inscription mercredi 15 novembre 2006 Statut Membre Dernière intervention 22 mai 2012
14 nov. 2010 à 16:35
Il y a beaucoup plus simple:
DecimalSeparator:='.';
et si l'on veut revenir à la virgule:
DecimalSeparator:=',';
0
Rejoignez-nous