SÉPARATEUR DE MILLIERS POUR ENTIERS

Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 - 15 juin 2013 à 00:54
 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 268 Date d'inscription mardi 24 juillet 2007 Statut Membre Dernière intervention 2 février 2021 1
20 juin 2013 à 15:41
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 268 Date d'inscription mardi 24 juillet 2007 Statut Membre Dernière intervention 2 février 2021 1
20 juin 2013 à 15:06
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 268 Date d'inscription mardi 24 juillet 2007 Statut Membre Dernière intervention 2 février 2021 1
20 juin 2013 à 13:53
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 268 Date d'inscription mardi 24 juillet 2007 Statut Membre Dernière intervention 2 février 2021 1
20 juin 2013 à 10:31
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+.
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
19 juin 2013 à 20:37
re,

juste un petit mot au sujet de la fonction Format en assembleur ...

si vous l'utilisez que pour convertir un entier "%d" vous pouvez
utilisez IntToStr à la place ... cette fonction utilise le même code assembleur
pour la conversion des Int64 que Format mais elle est bien évidement plus courte ;-)
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
19 juin 2013 à 20:16
Tiens l'update de la capture écran apparait!

@Pseudo3
J'ai étudié un peu le source de Format, elle est en assembleur mais intègre un tas de cas que l'on pourrait éliminer pour un gain de temps.
Quand je dis Assembleur, c'étais effectivement pour dire qu'il faudrait réécrire cette fonction...

Pour l'instant la version 6 de votre fonction me convient en terme de performance...

Si j'avais le temps, je m'attaquerai un peu à l'assembleur...
A+
cs_pseudo3 Messages postés 268 Date d'inscription mardi 24 juillet 2007 Statut Membre Dernière intervention 2 février 2021 1
19 juin 2013 à 13:45
Bonjour,

@Jean_Jean : " La fonction version 7 de Korgis ne pourra pas fonctionner en D7..."
Bin dans ce cas tu peux prendre la version 6, IntToSepStr6, Korgis a dit qu'elle "est béton" (le 18/06/2013 14:19:25) ... d'ailleurs la version 7 visait comme la 6 à soulager la boucle mais différemment.

"Mais à mon avis, seul l'assembleur permettra une amélioration sensible de la performance" : Cela dépend car pour l'essentiel on n'utilise ici que :
- la fonction Format qui date de D1 et qui est certainement déjà en ASM,
- et la procédure Insert qui est peut-être aussi déjà en ASM,
et si elles sont déjà toutes deux en ASM on risquerait tout simplement de ne rien améliorer.

Et puis grâce à ton comparateur de perfs je sais qu'il faut chez moi 46 ms pour convertir un Int64 10 000 fois.
Or la routine ne sera généralement utilisée que pour améliorer la lisibilité de l'affichage d'un résultat et qui dit lisibilité dit qu'il faut laisser du temps pour lire c'est à dire plusieurs secondes à mon avis, et comme on n'a pas besoin pour ça de convertir 10 000 fois mais qu'une seule et unique fois suffit cette conversion prend 0,0046 millisecondes.

A+.
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
19 juin 2013 à 12:53
- Je vois que vous fignolez toujours! Bravo
Sauf erreur de ma part, La fonction version 7 de korgis ne pourra pas fonctionner en D7 car la valeur absolue de Low(int64) n'est pas accepter. Voir ma première fonction qui permet de contourner ce problème.
Je regarderai plus en détail vos ajouts pour voir si je dois faire une mise à jour. Mais à mon avis, seul l'assembleur permettra une amélioration sensible de la performance

- Quand j'ai fait ma dernière mise à jour, je n'avais vu aucun message après le 17/06/2013.
Il semble en effet qu'il y a quelques soucis du côté de la mise en ligne. La capture d'écran updaté n'a pas été prise en compte alors qu'elle apparaissait dans la liste des codes sur la page d'accueil!

A+
cs_pseudo3 Messages postés 268 Date d'inscription mardi 24 juillet 2007 Statut Membre Dernière intervention 2 février 2021 1
19 juin 2013 à 09:39
Bonjour,

@KORGIS : "C'est possible, même si la différence n'est pas décelable vu que l'instruction n'est pas répétée dans la boucle."
Entièrement d'accord. En plus j'avais bien dit "histoire de chinoiser un peu".

"Par ailleurs, ce conseil figure dans l'aide de D7, et pas dans celle de D4."
Pour info je te signale qu'il figure aussi dans celles de D5 et D6.

"Il serait sans doute intéressant de savoir s'il s'applique à tous les compilateurs.
Chez moi, sous D4, testé avec GetTickCount dans des boucles "monstrueuses", aucune différence ni dans un sens ni dans l'autre" :
Bin cette problématique est en conséquence résolue : s'il n'y a aucune différence dans certains cas mais que ça apporte du gain de speed dans les autres cas autant accorder systématiquement la priorité à l'utilisation de l'opérateur plus sur deux chaînes.

A+.
korgis Messages postés 420 Date d'inscription samedi 17 mai 2003 Statut Membre Dernière intervention 6 mai 2019 17
18 juin 2013 à 20:18
@pseudo3 :
"Conseil : L'opérateur plus est plus rapide que Concat. " Fin de citation.
... Et donc, vu ce conseil, vaut mieux remplacer Result := Concat('-', Result) par Result := '-' + Result."

C'est possible, même si la différence n'est pas décelable vu que l'instruction n'est pas répétée dans la boucle.
Par ailleurs, ce conseil figure dans l'aide de D7, et pas dans celle de D4.
Ce qui fait que j'ai toujours eu un doute...
Il serait sans doute intéressant de savoir s'il s'applique à tous les compilateurs.
Chez moi, sous D4, testé avec GetTickCount dans des boucles "monstrueuses", aucune différence ni dans un sens ni dans l'autre.
cs_pseudo3 Messages postés 268 Date d'inscription mardi 24 juillet 2007 Statut Membre Dernière intervention 2 février 2021 1
18 juin 2013 à 15:19
Re-bonjour,

@KORGIS : Ok pour ta version IntToSepStr7(Value: Int64) avec Result := Concat('-', Result) ... Mais histoire de chinoiser un peu je viens de voir ce que dit l'aide Delphi à propos de Concat :

" Extrait : Description

Utilisez Concat afin de concaténer un nombre arbitraire de chaînes. Chaque paramètre est une expression de type chaîne. Le résultat est la concaténation de tous les paramètres chaîne.

L'utilisation de l'opérateur plus (+) sur deux chaînes a le même effet que l'utilisation de la fonction Concat :

S := 'ABC' + 'DEF';

Conseil : L'opérateur plus est plus rapide que Concat. " Fin de citation.
... Et donc, vu ce conseil, vaut mieux remplacer Result := Concat('-', Result) par Result := '-' + Result.

A+.
korgis Messages postés 420 Date d'inscription samedi 17 mai 2003 Statut Membre Dernière intervention 6 mai 2019 17
18 juin 2013 à 14:42
@Jean_Jean :

je vois que tu viens de mettre à jour.
On va te faire tourner en bourrique...
Désolé ;-)
korgis Messages postés 420 Date d'inscription samedi 17 mai 2003 Statut Membre Dernière intervention 6 mai 2019 17
18 juin 2013 à 14:19
Et les problèmes de cache sous Firefox 20.0.1 continuent...

@pseudo3 : ta dernière version, IntToSepStr6, est béton, je n'ai pas pu la mettre en défaut dans mes tests.
J'avais fait ça, aussi, qui n'amène rien de plus (qui n'enlève rien non plus...).
Car c'est vrai que si l'on peut éviter de vérifier en permanence la condition "si le nombre est négatif" dans une boucle, c'est bien mieux (le péril jaune, coco... ;-).
Donc voici IntToSeptr7 à rajouter à la collection.
Mon préféré (avec IntToSepStr6 ^^)...

function IntToSepStr7(Value: Int64): string; // moi
var
i: Integer;
begin
Result := Format('%d', [Abs(Value)]);
i := Length(Result) + 1;
while (i > 4) do
begin
Dec(i, 3);
Insert(' ', Result, i);
end;
if Value < 0 then
Result := Concat('-', Result);
end;

P-S: débat animé autour d'un bout de code : ça manquait un peu ces derniers temps dans la petite communauté delphifr. Dommage, c'est ce qui fait le plaisir qu'on a à s'y retrouver...
cs_pseudo3 Messages postés 268 Date d'inscription mardi 24 juillet 2007 Statut Membre Dernière intervention 2 février 2021 1
18 juin 2013 à 12:07
Re-bonjour KORGIS,

1) "Attention, problème sur CodeS-SourceS..." : Oui c'est d'autant plus agaçant qu'en plus, après avoir vidé le cache il faut se ré-autentifier et on saute automatiquement vers le début de la discussion et en revenant à la fin de la discussion les derniers commentaires ont disparu ... et du coup faut d'abord quitter le site puis y revenir pour passer à la suite : la galère !!!

2) Nombre de Graham : Comme tu le dis "Faut laisser refroidir..." : c'est comme l'histoire des fans du plus grand nombre premier. J'en ai vu un qui s'étalait sur environ 80 pages en Arial 10 ... mais rien ne me prouvait que c'était réellement un nombre premier car pour vérifier que c'est un premier faut s'accrocher.

3) A propos de "je n'aime pas charger la mûle avec des tests en plein dans une boucle"
C'est pourtant toi qui dis que la vitesse d'exécution est négligeable :
"je suis persuadé que la différence de vitesse est très inférieure au temps requis pour lire" :
... C'est exact que j'ai dit ceci, mais rien n'empêche de fignoler pendant qu'on y est ... et puis on sera prêts si un chinois s'en mêle pour gagner encore quelques micro-secondes.
korgis Messages postés 420 Date d'inscription samedi 17 mai 2003 Statut Membre Dernière intervention 6 mai 2019 17
18 juin 2013 à 11:29
@pseudo3,
Je viens de "rafraîchir".

Oui, ça a l'air bien.

"je n'aime pas charger la mûle avec des tests en plein dans une boucle"
C'est pourtant toi qui dis que la vitesse d'exécution est négligeable :
"je suis persuadé que la différence de vitesse est très inférieure au temps requis pour lire"

;-)
korgis Messages postés 420 Date d'inscription samedi 17 mai 2003 Statut Membre Dernière intervention 6 mai 2019 17
18 juin 2013 à 11:24
Bonjour pseudo3,

Attention, problème sur CodeS-SourceS depuis un certain temps déjà, certains messages n'apparaissent pas dans les commentaires, alors qu'il sont néanmoins signalés par mail (si l'on a coché l'option).
Une des solutions est de vider le cache du navigateur.

En effet, je précisais dans un message précédent que les fonctions de formatage Delphi avaient une limitation liée au fait qu'à partir d'un longueur de 18 chiffres le nombre était affiché en notation scientifique.
L'étendue étant donc -999999999999999999..999999999999999999.
Donc ça n'est pas tout à fait satisfaisant.
On est assez d'accord là-dessus.
Même si l'on n'utilise pas souvent ces très grands nombres.
Sauf dans les banques suisses, Singapour, et autres places offshore...

@Cari : merci pour le nombre de Graham, je m'endormirai moins c.. ce soir, même si je me suis raisonnablement arrêté après avoir saisi le concept d'hypercube. Faut laisser refroidir...
cs_pseudo3 Messages postés 268 Date d'inscription mardi 24 juillet 2007 Statut Membre Dernière intervention 2 février 2021 1
18 juin 2013 à 11:21
Re-bonjour,

KORGIS : "Si tu enlèves cette instruction (le if Result[i - 1] in ['0'..'9']), quand si i - 1 = '-', un espace est ajouté entre le signe "-".
Ce qui fait que, selon les cas, un coup il y a un espace entre "-" et le nombre, un coup il n'y est pas (selon la longueur).
On peut ne pas trouver ça gênant, moi j'aime pas...

T'as bien le droit de ne pas aimer ça ... par contre moi je n'aime pas charger la mûle avec des tests en plein dans une boucle, et pour éviter l'espace entre "-" et le nombre je préfère ceci :

function IntToSepStr6(n: Int64): string;
var i, imin: integer;
begin
result := Format('%d',[n]);
if Result[1]='-' then imin:=5 else imin:=4;
i := length(Result) + 1;
while i > imin do begin
dec(i, 3); Insert(' ', Result, i);
end;
end;

Et voici les résultats :
Résultats pour Valeur = -9223372036854775808
Avec IntToSepStr6 -> [-9 223 372 036 854 775 808]

Résultats pour Valeur = -922337203685477580
Avec IntToSepStr6 -> [-922 337 203 685 477 580]

Résultats pour Valeur = -92233720368547758
Avec IntToSepStr6 -> [-92 233 720 368 547 758]

Résultats pour Valeur = -9223372036854775
Avec IntToSepStr6 -> [-9 223 372 036 854 775]

Résultats pour Valeur = -922337203685477
Avec IntToSepStr6 -> [-922 337 203 685 477]

Résultats pour Valeur = -92233720368547
Avec IntToSepStr6 -> [-92 233 720 368 547]

Résultats pour Valeur = -9223372036854
Avec IntToSepStr6 -> [-9 223 372 036 854]

Résultats pour Valeur = -922337203685
Avec IntToSepStr6 -> [-922 337 203 685]

Résultats pour Valeur = -92233720368
Avec IntToSepStr6 -> [-92 233 720 368]

Résultats pour Valeur = -9223372036
Avec IntToSepStr6 -> [-9 223 372 036]

Résultats pour Valeur = -922337203
Avec IntToSepStr6 -> [-922 337 203]

Résultats pour Valeur = -92233720
Avec IntToSepStr6 -> [-92 233 720]

Résultats pour Valeur = -9223372
Avec IntToSepStr6 -> [-9 223 372]

Résultats pour Valeur = -922337
Avec IntToSepStr6 -> [-922 337]

Résultats pour Valeur = -92233
Avec IntToSepStr6 -> [-92 233]

Résultats pour Valeur = -9223
Avec IntToSepStr6 -> [-9 223]

Résultats pour Valeur = -922
Avec IntToSepStr6 -> [-922]

Résultats pour Valeur = -92
Avec IntToSepStr6 -> [-92]

Résultats pour Valeur = -9
Avec IntToSepStr6 -> [-9]

J'ai affiché les résultats entre crochets [] pour montrer qu'il n'y a pas d'espace superflu ni devant ni derrière.

A +.
cs_pseudo3 Messages postés 268 Date d'inscription mardi 24 juillet 2007 Statut Membre Dernière intervention 2 février 2021 1
18 juin 2013 à 11:07
Re-bonjour,

KORGIS : "Il me semble pour finir que le premier code que je suggérais, inspiré par l'intervention de Cirec, était de loin le plus simple et peut-être le plus efficace :
function IntToSepStr(Value: Int64): string;
begin
Result := Format('%.0n', [Value/1]);
end;

... function IntToSepStr4(Value: Int64): string;
... function IntToSepStr5(Value: Int64): string; "

Désolé, mais ces 3 fonctions ne fonctionnent pas correctement dans le cas où l'Int64 vaut -9223372036854775808 car dans ce cas j'obtiens les résultats suivants :
Avec IntToSepStr -> -9,22337203685477581E18
Avec IntToSepStr4 -> -9,22337203685478E18
Avec IntToSepStr5 -> -9,22337203685477581E18

A+.
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
18 juin 2013 à 08:49
Et connaissez-vous le plus grand nombre apparaissant dans une démonstration mathématique ? :D

- C'est le nombre de Graham.

Mais celui-là, on ne l'écrit pas avec séparateur de millier. L'allonger ne serait pas raisonnable.
korgis Messages postés 420 Date d'inscription samedi 17 mai 2003 Statut Membre Dernière intervention 6 mai 2019 17
18 juin 2013 à 00:15
@Jean_Jean

Tu as écrit (j'avais pas fait gaffe) que :
"La fonction Format est valide de Low(Integer) à high(Integer) mais ne fonctionne pas pour les Int64"
Ce n'est pas vraiment exact.
En passant par les fonctions de formatage de Delphi, il semblerait que l'on soit limité à un étendue de -999999999999999999..999999999999999999, soit 18 chiffres, au-delà desquels l'affichage se fait en notation scientifique.
Mais bon, ça laisse quand même pas mal de marge, je trouve... :p

Voici pour le fun deux méthodes supplémentaires, avec la limitation décrite ci-dessus, mais qui fonctionnenent tout aussi bien :

function IntToSepStr4(Value: Int64): string;
begin
Result := FormatFloat(',0', Value);
end;

function IntToSepStr5(Value: Int64): string;
begin
Result := FloatToStrF(Value, ffNumber, 18, 0);
end;

Bonne nuit, les petits...
korgis Messages postés 420 Date d'inscription samedi 17 mai 2003 Statut Membre Dernière intervention 6 mai 2019 17
17 juin 2013 à 20:09
Je reposte en espaçant les paragraphes pour gagner en lisibilité !

@pseudo3
Tu dis :
"A mon avis le test if Result[i - 1] in ['0'..'9'] est superflu car c'est dans la ligne du début Result := Format('%d', [Value]) ou en amont qu'il y aurait un plantage si la Value incluait un digit autre que '0'..'9'."
Si tu enlèves cette instruction, quand si i - 1 = '-', un espace est ajouté entre le signe "-".
Ce qui fait que, selon les cas, un coup il y a un espace entre "-" et le nombre, un coup il n'y est pas (selon la longueur).
On peut ne pas trouver ça gênant, moi j'aime pas...

Tu dis :
""insérer "Result := TrimLeft(Result)" à la dernière ligne de ta fonction" : superflu avec while (i > 4) do on ne risque pas d'insérer un espace de trop à gauche.
... et au passage on revient à la simplicité."
Oui, mais toi tu codais "while i > 0", pas "while i > 4", donc ma suggestion s'appliquait à ton code. Cela devient inutile dans le mien.
Je ne l'y ai d'ailleurs pas utilisé si tu regardes bien.

Quand à la vitesse, tout à fait d'accord, vraiment négligable dans le contexte.

Il me semble pour finir que le premier code que je suggérais, inspiré par l'intervention de Cirec, était de loin le plus simple et peut-être le plus efficace :
function IntToSepStr(Value: Int64): string;
begin
Result := Format('%.0n', [Value/1]);
end;

Rien n'est si simple, en fait, hein ?

Bonne soirée à tous ;-)
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
17 juin 2013 à 19:08
Yo les amis!

1. Oui j'avais testé vite fait sans analyser la fonction de pseudo. Ce qui m'avait plu, c'était l'utilisation de Format qui effectivement est très rapide du fait d'appel direct en assembleur.

2. mais si certaines valeurs plantent le code, alors la fonction est disqualifiée

3. Dans ma mise à jour je vais publier la performance des fonctions valides uniquement.
Ce qui me gêne si on doit se pencher sur la performance, ce sont des instructions comme insert à mon avis plus lentes que des affectations directes dans une boucle...

4. Je mettrai donc au banc d'essai les fonctions pour les départager
cs_pseudo3 Messages postés 268 Date d'inscription mardi 24 juillet 2007 Statut Membre Dernière intervention 2 février 2021 1
17 juin 2013 à 17:19
Re-bonjour,

A mon avis le test if Result[i - 1] in ['0'..'9'] est superflu car c'est dans la ligne du début Result := Format('%d', [Value]) ou en amont qu'il y aurait un plantage si la Value incluait un digit autre que '0'..'9'.

"il peut rester un espace entre le signe - et le nombre, ce qui n'est pas très rigoureux"
... c'est pas gênant cela ne nuit pas à la lisibilité d'un résultat qu'on affiche.

"insérer "Result := TrimLeft(Result)" à la dernière ligne de ta fonction" : superflu avec while (i > 4) do on ne risque pas d'insérer un espace de trop à gauche.
... et au passage on revient à la simplicité.

"Sinon, il faudrait mesurer comparativement les vitesses d'exécution pour les départager sur ce critère" : Cela pourrait se faire ... par contre ce type de fonction n'étant destiné à être utilisé que pour améliorer la lisibilité d'un résultat affiché et qu'il faut laisser à l'utilisateur du temps pour lire je suis persuadé que la différence de vitesse est très inférieure au temps requis pour lire.

A+.
korgis Messages postés 420 Date d'inscription samedi 17 mai 2003 Statut Membre Dernière intervention 6 mai 2019 17
17 juin 2013 à 15:31
J'y reviens (j'ai un peu de temps à tuer...).
D'ailleurs, TrimLeft ne suffit pas : il peut rester un espace (ou pas) entre le signe - et le nombre, ce qui n'est pas très rigoureux.
Donc, à mon avis, sauf erreur, il faudrait faire (et le code s'alourdit):

function IntToSepStr3(Value: Int64): string;
var
i: Integer;
begin
Result := Format('%d', [Value]);
i := Length(Result) + 1;
while (i > 4) do
begin
Dec(i, 3);
if Result[i - 1] in ['0'..'9'] then
Insert(' ', Result, i);
end;
end;
Vous avez dit simple ?
;-)
korgis Messages postés 420 Date d'inscription samedi 17 mai 2003 Statut Membre Dernière intervention 6 mai 2019 17
17 juin 2013 à 14:35
@pseudo3
C'est peut-être pas compliqué, mais ça n'est jamais inintéressant d'essayer de trouver la meilleure (ou la moins mauvaise) solution, si ?
Simple, simple...
Néanmoins, n'oublie pas d'insérer "Result := TrimLeft(Result)" à la dernière ligne de ta fonction...^^
Sinon, il faudrait mesurer comparativement les vitesses d'exécution pour les départager sur ce critère.
Paraîtrait que "Format" est très rapide...
cs_pseudo3 Messages postés 268 Date d'inscription mardi 24 juillet 2007 Statut Membre Dernière intervention 2 février 2021 1
17 juin 2013 à 10:33
Re Bonjour,

A propos de "Je vais l'insérer dans une prochaine mise à jour!"

Bin comme le tuto de Foxi dit au sujet du %d de la fonction Format que les Types supportés sont : integer, smallint, shortint, longint, byte, word, int64, et cardinal.
il ne reste plus qu'à faire les variantes overlodées.

Puis on pourrait faire un truc similaire pour les nombres réels en insérant une espace tous les 3 pas vers la gauche, puis vers la droite, à partir de la position du DecimalSeparator.

A+.
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
17 juin 2013 à 10:15
Salut Pseudo!

bien joué! Ta solution est un peu mieux que la mienne.
Je vais l'inérer dans une prochaine mise à jour!

Au départ, j'étais parti uniquement sur les intéger. Puis j'ai voulu supprimer ce code lorsque je me suis rendu compte que format faisait l'affaire. Puis chacun y allait de son commentaire alors on l''a laissé.

C'est bien comme ça, chacun améliore un peu plus à chaque fois.
cs_pseudo3 Messages postés 268 Date d'inscription mardi 24 juillet 2007 Statut Membre Dernière intervention 2 février 2021 1
17 juin 2013 à 09:59
Bonjour,

Faudrait que l'on m'explique quel est l'intérêt d'une solution aussi compliquée pour insérer un simple espace tous les 3 pas dans une chaîne.
Pour ma part je me contente de ceci :

function IntToSepStr2(n: Int64): string;
var i: integer;
begin
Result := Format('%d',[n]); i := length(Result) + 1;
while i > 0 do begin
dec(i, 3); Insert(' ', Result, i);
end;
end;

A+.
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
17 juin 2013 à 09:21
Salut Yves Simon:
Word 0 to 65,535
SmallInt -32,768 to 32,767
LongWord 0 to 4,294,967,295
Cardinal 0 to 4,294,967,295
LongInt -2,147,483,648 to 2,147,483,647
Integer -2,147,483,648 to 2,147,483,647
Int64 -9,223,372,036,854,775,808 to
9,223,372,036,854,775,807
IntToSepStr fonctionnent pour integer et Int64. Pour les autres je n'ai pas vérifié. En particulier pour Cardinal, il faudrait adapter la fonction...
yvessimon Messages postés 637 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 9 janvier 2017
17 juin 2013 à 09:04
Bonjour,

De si grands nombres que représentent-t-il ?

Salutations
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
15 juin 2013 à 16:21
Bon, ben alors, je transforme le code maintenant avec la fonction de korgis en plus et fait un lien vers le tutorial de Foxi.

Comme ça tout le monde sera content!
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
15 juin 2013 à 16:10
y a pas de soucis ... je la supprimerai dans la soirée ...

mais pour le snippet peu importe qui le dépose ... il suffit d'y joindre le lien vers
le tutoriel de f0xi ;)
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
15 juin 2013 à 14:11
Le comble, c'est que j'avais utilisé la solution en 2012 et que j'avais signalé en commentaire du tutorial de Foxi!

Mais bon, pourquoi laisser ce source maintenant, c'est idiot...

Bon enfin faites comme vous voulez!
korgis Messages postés 420 Date d'inscription samedi 17 mai 2003 Statut Membre Dernière intervention 6 mai 2019 17
15 juin 2013 à 13:51
Oui, c'est vrai.
Ce tutoriel by f0xi est incontournable, à mettre obligatoirement dans ses favoris.
Et à consulter régulièrement.
N'empêche que le snippet, hein, je trouve qu'il aurait de la gueule :

function IntToSepStr(Value: Int64): string;
begin
Result := Format('%.0n', [Value/1]);
end;

Et utile, avec ça...
César devrait y songer.
(à moins qu'il n'y figure déjà, mais j'y ai pas vu...)
korgis Messages postés 420 Date d'inscription samedi 17 mai 2003 Statut Membre Dernière intervention 6 mai 2019 17
15 juin 2013 à 13:18
Joli, le "Nombre/1" pour contourner le transtypage refusé par le compilateur...
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
15 juin 2013 à 09:27
Mince alors! J'avais cru l'essayé pourtant.

Bon alors, je suggère de supprimer ce cource inutile

Merci
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
15 juin 2013 à 00:54
Salut,

je crois que t'es passé à coté d'un truc !!!

essayes voir ceci:

LbNbSep.Caption := format('Taille : %.0n octets', [Nombre/1]);

@++