Pascal
Fermé
zigzagart
-
11 janv. 2012 à 01:03
[Dal] Messages postés 6057 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 17 mars 2023 - 12 janv. 2012 à 20:10
[Dal] Messages postés 6057 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 17 mars 2023 - 12 janv. 2012 à 20:10
A voir également:
- Pascal
- Turbo pascal download - Télécharger - Édition & Programmation
- My pascal - Télécharger - Édition & Programmation
- Uses crt pascal - Forum Pascal
- Pascal veut modifier une photo mais c’est la visionneuse d’images qui l’ouvre. que doit-il choisir pour l’ouvrir avec son logiciel de traitement d’image ? - Forum Windows
- Dev-pascal - Télécharger - Édition & Programmation
4 réponses
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
11 janv. 2012 à 05:20
11 janv. 2012 à 05:20
Le moyen le plus pratique est de calculer les chiffres qui composent le nombre dans la base de ton choix, décimal je suppose, en les comptant :
Nb_Chiffres:= 0;
While Valeur > 0 do
begin
Valeur:= Valeur div 10;
Inc(Nb_Chiffres);
end;
KX
Messages postés
16668
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2023
3 005
11 janv. 2012 à 08:00
11 janv. 2012 à 08:00
Un peu de maths et c'est bon...
function nbChiffres(const n:integer):integer;
begin
result:=1+round(ln(abs(n))/ln(10));
end;
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
11 janv. 2012 à 17:26
11 janv. 2012 à 17:26
Ha oui ! C'est vrai que c'est pas mal !
Et après quelques tests, j'ai pu remarquer que la rapiditée d'exécution s'équilibre dès que l'on monte dans le nombre de chiffres en présence.
Seul petit bémol : le code asm est un peu plus encombrant (*2)...
Et après quelques tests, j'ai pu remarquer que la rapiditée d'exécution s'équilibre dès que l'on monte dans le nombre de chiffres en présence.
Seul petit bémol : le code asm est un peu plus encombrant (*2)...
KX
Messages postés
16668
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2023
3 005
11 janv. 2012 à 19:44
11 janv. 2012 à 19:44
le code asm est un peu plus encombrant
Quand je compile (avec Dev-Pascal) les deux programmes font la même taille : 14 848 octets
Mais ce n'est peut-être pas ce que tu appelles "code asm"
Quand je compile (avec Dev-Pascal) les deux programmes font la même taille : 14 848 octets
Mais ce n'est peut-être pas ce que tu appelles "code asm"
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
11 janv. 2012 à 20:55
11 janv. 2012 à 20:55
Si si c'est bien ce que j'appelle le code asm, le code assembleur en fait, et j'obtiens 32 octets de différence...Pour 29 octets pour le While ! Mais c'est sous delphi, et sa notion d'optimisation est on ne peut plus approximative malgré les réglages, et il faut croire que Dev-Pascal fait beaucoup mieux, ce qui est plutôt rassurant !
KX
Messages postés
16668
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2023
3 005
>
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
11 janv. 2012 à 21:01
11 janv. 2012 à 21:01
On n'a peut-être pas testé tout à fait le même code, j'avais transformé le tien en fonction pour coller au mien :
Mais bon pour 32 octets de différence...
function Nb_Chiffres(Valeur:integer):integer;
begin
Nb_Chiffres:= 0;
While Valeur > 0 do
begin
Valeur:= Valeur div 10;
Inc(Nb_Chiffres);
end;
end;
Mais bon pour 32 octets de différence...
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
Modifié par nicocorico le 11/01/2012 à 21:31
Modifié par nicocorico le 11/01/2012 à 21:31
Oui, je te l'accorde !
Et puis ta solution tiens compte des nombre négatifs, ce qui équilibre un peu la différence de taille.
De toute manière, malgré que je ne suis pas très fan du FPU, trop souvent plus lent, la solution Ln est attractive, et je pense déjà à quelques anciennes routines ou elle pourrait être améliorative... Donc, merci !
Et puis ta solution tiens compte des nombre négatifs, ce qui équilibre un peu la différence de taille.
De toute manière, malgré que je ne suis pas très fan du FPU, trop souvent plus lent, la solution Ln est attractive, et je pense déjà à quelques anciennes routines ou elle pourrait être améliorative... Donc, merci !
[Dal]
Messages postés
6057
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
17 mars 2023
1 043
11 janv. 2012 à 21:11
11 janv. 2012 à 21:11
On peut aussi convertir l'entier en chaine et obtenir sa longueur.
Dal
Length(IntToStr(Valeur))
Dal
KX
Messages postés
16668
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2023
3 005
11 janv. 2012 à 21:16
11 janv. 2012 à 21:16
ça pose juste un problème pour les nombres négatifs, mais nicocorico ne prenait pas non plus ce cas en compte (moi je l'ai mis surtout à cause du log... même si ça n'empêche pas de planter à 0 ;-)
[Dal]
Messages postés
6057
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
17 mars 2023
1 043
Modifié par [Dal] le 12/01/2012 à 11:29
Modifié par [Dal] le 12/01/2012 à 11:29
Ah, les entiers négatifs.
Dans ton code, tu retournes 0 si Valeur := -12345, ce qui me parait inexact. Il y a bien 5 chiffres dans cet entier.
Pour prendre en compte ce cas dans ma proposition, on peut ajouter un test. Si Valeur < 0, on retire 1 à la longueur obtenue.
Cela fait tout de même un code plus simple et avec nettement moins de calculs :-D
Enfin, on peut toujours améliorer.
Dal
Dans ton code, tu retournes 0 si Valeur := -12345, ce qui me parait inexact. Il y a bien 5 chiffres dans cet entier.
Pour prendre en compte ce cas dans ma proposition, on peut ajouter un test. Si Valeur < 0, on retire 1 à la longueur obtenue.
Nb_Chiffres := Length(IntToStr(Valeur)); if Valeur < 0 then Dec(Nb_Chiffres);
Cela fait tout de même un code plus simple et avec nettement moins de calculs :-D
Enfin, on peut toujours améliorer.
Dal
KX
Messages postés
16668
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2023
3 005
12 janv. 2012 à 15:52
12 janv. 2012 à 15:52
C'est le code de nicocorico qui renvoit 0 si le nombre est inférieur à 0.
Dans le mien les nombres négatifs sont pris en compte avec l'appel de la fonction abs.
Le seul cas qui bug, c'est n=0, mais avec un petit if ça se règle vite.
Par contre avec le recul, round ne convient pas du tout, c'est plutôt trunc qu'il faut prendre ici :
Dans le mien les nombres négatifs sont pris en compte avec l'appel de la fonction abs.
Le seul cas qui bug, c'est n=0, mais avec un petit if ça se règle vite.
Par contre avec le recul, round ne convient pas du tout, c'est plutôt trunc qu'il faut prendre ici :
1+trunc(ln(abs(n))/ln(10));
[Dal]
Messages postés
6057
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
17 mars 2023
1 043
12 janv. 2012 à 20:10
12 janv. 2012 à 20:10
Désolé pour la confusion.
Abs est une bonne idée, en l'adoptant à mon tour, cela me permet de supprimer mon if :
;-D
Dal
Abs est une bonne idée, en l'adoptant à mon tour, cela me permet de supprimer mon if :
Nb_Chiffres := Length(IntToStr(Abs(Valeur)));
;-D
Dal