SÉPARATEUR DE MILLIERS POUR ENTIERS

Messages postés
3809
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
1 septembre 2019
- - Dernière réponse :  Mentor - 29 mai 2016 à 16:08
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/55223-separateur-de-milliers-pour-entiers

Bonjour,
Je ne tombe sur cet article que maintenant..
Un moyen très simple d'écrire un entier avec les séparateurs de milliers est d'utiliser FloatToStrF en spécifiant le mode ffNumber et 0 chiffre après la virgule.

Exemple : FloatToStrF (Valeur à convertir, ffNumber, 18, 0)
cs_pseudo3
Messages postés
270
Date d'inscription
mardi 24 juillet 2007
Statut
Membre
Dernière intervention
7 juin 2018
-
Re-bonjour,

Tentative d'amélioration de la fonction IntToSepStr : voici la version 8 qui n'utilise pas la procédure Insert :

function IntToSepStr8(const n: Int64): string;
var i, ls, lr, pas: integer; sr: string; ps, pr: PChar;
begin
result := Format('%d', [n]);
if n < 0 then Delete(Result, 1, 1);
ls := length(Result);
lr := ls + (ls div 3);
if ls mod 3 = 0 then lr := lr - 1;
Setlength(sr,lr);
ps := @result[ls]; pr := @sr[lr];
pas := 0;
for i := lr downto 1 do begin
if pas < 3 then begin
pr^ := ps^; inc(pas); dec(pr); dec(ps);
end else begin
pr^ :=' ';
dec(pr); pas := 0;
end;
end;
if n >= 0 then Result := sr else result := '-' + sr;
end;

Résultats pour 500000 conversions du Int64 = -9223372036854775807 :
Avec IntToSepStr6 : mis 2480 ms
Avec IntToSepStr6 : Res = -9 223 372 036 854 775 807

Avec IntToSepStr8 : mis 2184 ms
Avec IntToSepStr8 : Res = -9 223 372 036 854 775 807Ecart de perfs relatif pour une seule conversion (2480 - 2184)/500000 0,0006 ms : clopinettes.

A+.
cs_pseudo3
Messages postés
270
Date d'inscription
mardi 24 juillet 2007
Statut
Membre
Dernière intervention
7 juin 2018
-
Re-bonjour,

Cirec : "si tu veux encore gagner un peu de temps regarde ici:
http://www.codyx.org/snippet_exclure-caracteres-chaine_376.aspx#1293

elle est ~deux fois plus rapide que la version de f0xi qui utilise les PChar
http://www.codyx.org/snippet_exclure-caracteres-chaine_376.aspx#1208"

J'ai fait un test comparatif en y ajoutant celle-ci :

function SupprUnChar(const S: string; const CharSuppr: Char): string;
var i, ls, lr: integer; ps, pr: PChar;
begin
ls := length(S);
if ls = 0 then begin result := ''; Exit; end;
Result := S;
ps := @S[1]; pr := @Result[1]; lr := 0;
for i := 1 to ls do
begin
if ps^ <> CharSuppr then begin pr^ := ps^; inc(lr); inc(pr); end;
inc(ps);
end;
SetLength(Result, lr);
end;

Résultats pour 500000 fois la suppression des espaces dans '-9 223 372 036 854 775 808' :
Avec ExcludeCharsCirec : mis 109 ms
Avec ExcludeCharsCirec : Res = -9223372036854775808

Avec ExcludeCharsFoxi : mis 94 ms
Avec ExcludeCharsFoxi : Res = -9223372036854775808

Avec SupprUnChar : mis 109 ms
Avec SupprUnChar : Res = -9223372036854775808
Ecart de perfs pour la suppression d'une seule fois (109 - 94) / 500000 0,00003 ms : on n'y gagnerait que des clopinettes.

A+.
cs_pseudo3
Messages postés
270
Date d'inscription
mardi 24 juillet 2007
Statut
Membre
Dernière intervention
7 juin 2018
-
Re-bonjour,

Cirec : "oui est ce encore le cas aujourd'hui ? ... il faudrait refaire le teste".

Voici les résultats du test pour 500000 conversions du Int64 = -9223372036854775807 :
Avec intToStr : mis 2012 ms
Avec intToStr : Res = -9223372036854775807

Avec Format : mis 1982 ms
Avec Format : Res = -9223372036854775807

L'écart de perfs entre intToStr et Format s'est réduit mais Format est un chouilla plus rapide.

A+.
cs_pseudo3
Messages postés
270
Date d'inscription
mardi 24 juillet 2007
Statut
Membre
Dernière intervention
7 juin 2018
-
Re-bonjour,

A propos de la routine :
function StrSepToInt64(Stn: string): Int64;
begin
result := StrToInt64(StringReplace(Stn, ' ', '', [rfReplaceAll, rfIgnoreCase]));
end;

Se souvenir que pour supprimer un caractère d'une string il y a plus rapide en utilisant des PChar :

function StrSepToInt64_V2(const Stn: string): Int64;

function TrimSpaces: string;
var i, lr: integer; ps, pr: PChar; begin Result :Stn; if Result '' then Exit;
ps := @Stn[1]; pr := @Result[1]; lr := 0;
for i := 1 to length(Stn) do
begin if ps^ <> ' ' then
begin pr^ := ps^; inc(lr); inc(pr); end;
inc(ps);
end;
SetLength(Result, lr);
end;

begin
Result := StrToInt64(TrimSpaces);
end;

Résultats des tests pour 100000 conversions de '-9 223 372 036 854 775 808' :
Avec StrSepToInt64 : mis 530 ms
Avec StrSepToInt64 : Res -9223372036854775808

Avec StrSepToInt64_V2 : mis 47 ms
Avec StrSepToInt64_V2 : Res -9223372036854775808
Donc StrSepToInt64_V2 environ 11 fois plus rapide que StrSepToInt64.

A+.