Comment calculer le nombre de chiffres d'un entier ?

Présentation
Il peut être parfois utile de connaître le nombre de chiffres que contient un nombre par exemple si l'on souhaite le convertir en chaîne de caractères à l'aide de la fonction sprintf.
Téléchargement
Compatibilité
Linux Mac Windows
0  0 
Téléchargé 19 fois Voir les 23 commentaires
Détails
Catégories : Algorithmes
Avatar de fearyourself
Expert éminent sénior
Voir tous les téléchargements de l'auteur
Licence : Non renseignée
Date de mise en ligne : 30 novembre 2010




Avatar de diogene diogene - Expert éminent sénior https://www.developpez.com
le 09/01/2012 à 11:38
@souviron34
Avec ton idée, on doit pouvoir utiliser une dichotomie pour optimser les seuils, et utiliser des else, ce qui évite des tests
Je ne pense pas qu'on puisse optimiser les choses au niveau des seuils. On ne peut pas utiliser des else sur ce code.

Si on pose que l'unsigned utilisé a au maximum M chiffres (décimaux), pour un nombre de N chiffres (décimaux), alors, sauf erreur,

1- Pour la méthode avec plein de if, on a M-N tests (il manque un if pour un unsigned de 32 bits) (ou N tests si on codait en ordre et en sens inverse les if).

2- La méthode de Djakisback donne une addition, un test et une division par boucle soit N tests + N additions + N divisions.

3- La méthode tabulée de souviron34 donne un test, 2 additions (et un déréférencement) par boucle soit N tests et 2N additions

4- La méthode "dichotomique" donne un nombre de tests, et d'opérations en log2(M). Le nombre de tests est P+1 si 2^(P-1)< M <= 2^P. Pour passer d'un M de 10 (unsigned de 32 bits)à M de 20 (unsigned de 64 bits), il suffit de rajouter un if(). le nombre d'additions est le nombre de 1 dans la représentation binaire de N-1 et le nombre de divisions est égal au nombre de 1, le lsb exclus, dans la représentation binaire de N-1. Pour un unsigned de 32 bits (M = 10) le pire cas sera pour N = 8 et pour un 64 bits (M=20) pour N = 16.

Si on tabule les pires cas :
                       unsigned 32 bits    unsigned 64 bits
                            M = 10            M = 20
                         tests  +   /        tests  +   /
méthode 1  (if)           9     0   0         19    0   0
méthode 2  (div/10)      10    10  10         20   20  20
méthode 3  (table)       10    20   0         20   40   0
méthode 4  (dicho)        5     3   2          6    4   3
A chacun de choisir en fonction de sa problématique.
Avatar de fearyourself fearyourself - Expert éminent sénior https://www.developpez.com
le 30/11/2010 à 15:36
Bonjour, Je vous propose un nouvel élément à utiliser : Comment calculer le nombre de chiffres d'un entier ?

Il peut être parfois utile de connaître le nombre de chiffres que contient un nombre par exemple si l'on souhaite le convertir en chaîne de caractères à l'aide de la fonction sprintf.

Qu'en pensez-vous ?
Avatar de Obsidian Obsidian - Modérateur https://www.developpez.com
le 06/01/2012 à 11:49
Citation Envoyé par shessuky Voir le message
int MyInt = 2012;
int NumberOfDigits = String.valueOf(MyInt).length();
//that should return 4
Formidable.

  • Ce que tu nous proposes n'est pas du C ;
  • Comment fonctionne « valueOf » ;
  • Comment t'y prendrais-tu si c'était à toi de l'écrire (pour que les autres puissent l'utiliser) ?
Avatar de Bktero Bktero - Modérateur https://www.developpez.com
le 06/01/2012 à 13:49
C'est du Java ça

EDIT : en regardant la source proposé, je me dis qu'il y a des propriétés de la fonction LOG que ne connait pas encore... Pourtant, j'en ai bouffé des maths pendant mes études

EDIT 2: http://forums.futura-sciences.com/mathematiques-superieur/16744-nombre-de-chiffre-de-lexpression-2-n.html Je me passerai un week-end en étant plus intelligent.
Avatar de valefor valefor - Membre éclairé https://www.developpez.com
le 06/01/2012 à 13:56
Citation Envoyé par Obsidian Voir le message
Comment fonctionne « valueOf »
Lis le man...

C'est pas sur un ton agressif que je dis cela, c'est juste que l'exemple proposé utilise aussi une fonction externe log10 (même si dans ce cas c'est du c standard).

Autres pistes : http://graphics.stanford.edu/~seande...erLog10Obvious
Avatar de Djakisback Djakisback - Membre émérite https://www.developpez.com
le 07/01/2012 à 21:56
Bonjour,
par curiosité j'ai testé la fonction fournie qui semble ne fonctionner que pour les nombres positifs, à cause des propriétés du logarithme ?

Du coup, un peu hors-sujet et toujours par curiosité, je me demandais ce que vous pensiez de cette fonction que j'ai pondue pour répondre au problème sans la lib math. D'après vous, est-ce qu'elle couvre tous les cas d'utilisation d'entiers (dans l'intervalle du type défini) et est-ce qu'elle serait optimisable ?

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
int nombre_chiffre2(int i)	{
	int c = 0;
	
	if(i < 0)	{
		 i = -i;
	}
	
	do	{
		c++;
	}
	while((i /= 10) > 0);
	return c;
}
Merci d'avance.
Avatar de Kirilenko Kirilenko - Membre éclairé https://www.developpez.com
le 08/01/2012 à 9:45
Bonjour,
par curiosité j'ai testé la fonction fournie qui semble ne fonctionner que pour les nombres positifs, à cause des propriétés du logarithme ?

Du coup, un peu hors-sujet et toujours par curiosité, je me demandais ce que vous pensiez de cette fonction que j'ai pondue pour répondre au problème sans la lib math. D'après vous, est-ce qu'elle couvre tous les cas d'utilisation d'entiers (dans l'intervalle du type défini) et est-ce qu'elle serait optimisable ?
Après avoir testé sur de nombreuses valeurs, force est de constater que cette fonction marche sur l'intervalle [-INT_MAX ; INT_MAX].
Bon, c'est pas la première fois qu'on voit cette fonction sur le Web, mais elle remplit son boulot.
Avatar de souviron34 souviron34 - Expert éminent sénior https://www.developpez.com
le 08/01/2012 à 12:13
et j'ajouteraais qu'elle va beaucoup plus vite que la fonction intitiale :

calculer un log est long (développemeny de Taylor), utilise des doubles, alors qu'on a besoin que d'arithmétique entière, et sans log

Mais on peut l'optimiser sans fair de division :

Code : Sélectionner tout
1
2
3
4
do	{
		c++;
	}
	while((i /= 10) > 0);
peut devenir, à base d'un tableau :

Code : Sélectionner tout
1
2
3
4
5
6
7
int tab[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000...} ;
int *p = tab ;

do	{
		c++;
	}
	while(*(p+c) < i);
le plus optimal...
Avatar de Djakisback Djakisback - Membre émérite https://www.developpez.com
le 08/01/2012 à 17:06
Merci pour vos réponses.
Pas mal, le coup du tableau
Developpez.com décline toute responsabilité quant à l'utilisation des différents éléments téléchargés.