Comment déterminer le nombre de chiffres d'un nombre naturel
4 participants
Auteur
Message
papydall
Nombre de messages : 7017 Age : 74 Localisation : Moknine (Tunisie) Entre la chaise et le clavier Date d'inscription : 03/03/2012
Sujet: Comment déterminer le nombre de chiffres d'un nombre naturel Mar 14 Nov 2023 - 2:17
Ce n'est vraiment pas très util, mais c'est astucieux
Comment déterminer le nombre de chiffres d'un nombre naturel non nul ? Transformer le nombre en chaine et déterminer sa longueur par la fonction len(str$(n)) ? Mais ça ne marche pas pour les grands nombres de plusieurs chiffres! Faites le test si vous en avez des doutes!
Voici une solution élégante, simple et efficace dans tous les cas : l'utilisation de la fonction logarithme décimal de n
Spoiler:
Code:
dim n n = 123456789987654321123456789987654321123456789987654321123456789987654321123456789987654321 print len(str$(n)) : ' <<<<<===== Résultat faux print " Le nombre n contient " ; int(log10(n)) + 1 ; " chiffres" : ' <<<=== OK
Dernière édition par papydall le Mer 15 Nov 2023 - 21:46, édité 1 fois
Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
Sujet: Re: Comment déterminer le nombre de chiffres d'un nombre naturel Mar 14 Nov 2023 - 9:42
L'astuce est jolie ! L'erreur vient de la représentation scientifique choisie par str$ pour les grands nombres.
Code:
dim n, s$ n = 123456789987654321123456789987654321123456789987654321123456789987654321123456789987654321 s$ = "123456789987654321123456789987654321123456789987654321123456789987654321123456789987654321" print str$(n) print len(s$) print len(str$(n)) : ' <<<<<===== Résultat faux print " Le nombre n contient " ; int(log10(n)) + 1 ; " chiffres" : ' <<<=== OK
jean_debord
Nombre de messages : 1266 Age : 70 Localisation : Limoges Date d'inscription : 21/09/2008
Sujet: Re: Comment déterminer le nombre de chiffres d'un nombre naturel Mer 15 Nov 2023 - 10:50
Je n'avais pas réalisé que Panoramic pouvait traiter d'aussi grands nombres !
Comment sont-ils stockés ? Peut-on faire des opérations avec ?
Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
Sujet: Re: Comment déterminer le nombre de chiffres d'un nombre naturel Mer 15 Nov 2023 - 11:39
Non, on ne peut pas faire des calculs avec de tels nombres, du moins pas en format flottant double précision de Delphi (ce qui est le cas de Panoramic).
Voici ce que dit la documentation:
Citation :
The Double type is an IEEE standard floating-point type that uses 8 bytes to store a sign bit, an 11-bit exponent, and a 52-bit mantissa. The mantissa is usually normalized, that is, it has an implicit 1 bit before the most significant bit. If the exponent is zero, however, the mantissa is denormalized—without the implicit 1 bit. Thus, the numerical value of +0.0 is represented by all zero bits. An exponent of all 1 bits represents infinity (mantissa is zero) or not-a-number (mantissa is not zero).
The limits of the Double type are approximately 2.23 × 10-308 to 1.79 × 10308, with about 15 decimal digits of precision. Table 5-1 shows the detailed format of finite and special Double values.
Donc, au-dela de 15 chiffres dans un nombre, on perd des informations. Il faut une collections de fonctions spéciales travaillant due des "entiers longs" ou flottants en quadruple précision (128 bits) pour y arriver. Et même dans ce cas (comme par exemple avec la très lourde biblipthèque MPFR, accès totalement libre), on ne dépasse pas 30 chiffres significatifs. Alor, 90 comme dans le code ci-dessus...
papydall
Nombre de messages : 7017 Age : 74 Localisation : Moknine (Tunisie) Entre la chaise et le clavier Date d'inscription : 03/03/2012
Sujet: Re: Comment déterminer le nombre de chiffres d'un nombre naturel Mer 15 Nov 2023 - 15:56
Merci Klaus. Merci Jean_Debord.
En faisant des recherches je suis tombé sur un projet tout à fait utile : Manipulation très rapide de très grands nombres entiers + fonctions de base de l'arithmétique modulaire,nombres premiers...
Dans cette librairie, un type Hugint est défini pour la manipulation de nombres entiers très grands, avec les fonctions correspondantes (addition, soustraction, multiplication et division). En plus les fonctions mathématiques de base sont implémentées : arithmétique modulaire, génération de nombres premiers très grands, exponentiation modulaire (Montgomery), résolution d'équations diophantiennes et de congruence, factorisation, ...
Les diverses fonctions sont codées en assembleur pour une manipulation très rapide.
Vous pouvez télécharger le projet (ou simplement jetter un oeil) ici
Dernière édition par papydall le Mer 15 Nov 2023 - 18:08, édité 2 fois
Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
Sujet: Re: Comment déterminer le nombre de chiffres d'un nombre naturel Mer 15 Nov 2023 - 16:29
J'ai téléchargé ce projet et je vais le regarder. Merci, Papydall, pour le lien !
J'étais en train d'analyser le projet "GMP for Delphi" téléchargeable ici et ici.
EDIT 15/11/2023 à 16:52: J'ai regardé le projet contenant le type de données HUGINT et j'ai pu le faire marcher facilement. Je vais l'intégrer dans KGF.dll et rendre ses fonctions accessibles.
Il y a essentiellement les 4 opérations de base, puis quelques fonctiions intrinsèques simples comme SQRT. Ce sont des calculs sur des entiers potentiellement énormes (dans la version par défaut, il s'agit de nombres couvrant jusqu'a 4096 mots de 32 bits !). Par contre, il n'y a pas de calcul de valeurs flottantes ce qui est le cas dans le projet que j'ai cité dans mon post. Mais ça reste très intéressant. Lorsqu'on s'intéresse au nombre de chiffres et non aux décimales, cela résoud parfaitement le problème. On peut aussi "simuler" les valeurs flottantes en "imaginant" une virgule quelque part (nombre en "fixed point"). Il faut alors placer la virgule en affichage, après les calculs, au bon endroit en fonction de l'opération utilisée. Donc, quelques lignes de programmation supplémentaires, mais rien de difficile).
jean_debord
Nombre de messages : 1266 Age : 70 Localisation : Limoges Date d'inscription : 21/09/2008
Sujet: Re: Comment déterminer le nombre de chiffres d'un nombre naturel Mer 15 Nov 2023 - 17:16
Klaus a écrit:
avec la très lourde bibliothèque MPFR, accès totalement libre), on ne dépasse pas 30 chiffres significatifs.
Dans MPFR on peut choisir la précision qu'on veut (voir les exemples dans FBCroco) mais les calculs deviennent de plus en plus longs quand la précision augmente.
J'utilise une version de GMP et MPFR adaptée pour FreeBASIC. Je ne sais pas s'il existe une adaptation pour Delphi ou Lazarus.
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
Sujet: Re: Comment déterminer le nombre de chiffres d'un nombre naturel Mer 15 Nov 2023 - 18:10
Je n'ai pas trouvé d'adaptation Delphi. Il y en a une pour FreePascal...
Mais le problème principal, c'est la licence. C'est une licence GPL, et donc il est exlu de faire des applications un tant soit peu professionnelles dès que ce sera payant. Je préfère les composant totalement libres de droit, d'autant qu'il y en a (comme celui cité par Papydall et celui que j'ai signalé dans mon post ci-dessue (GMP pour Delphi).
Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
Sujet: Re: Comment déterminer le nombre de chiffres d'un nombre naturel Jeu 16 Nov 2023 - 1:11
@Papydall: J'ai intégré le module de HugInteger dans KGF.dll et je l'ai publié,, avec les 8 primières fonctions de base. C'est assez impressionnant. Merci à toi pour l'information !
papydall
Nombre de messages : 7017 Age : 74 Localisation : Moknine (Tunisie) Entre la chaise et le clavier Date d'inscription : 03/03/2012
Sujet: Re: Comment déterminer le nombre de chiffres d'un nombre naturel Jeu 16 Nov 2023 - 6:00
Merci Klaus! Beau travail!
jean_debord
Nombre de messages : 1266 Age : 70 Localisation : Limoges Date d'inscription : 21/09/2008
Sujet: Re: Comment déterminer le nombre de chiffres d'un nombre naturel Jeu 16 Nov 2023 - 10:08
J'ai essayé de faire une DLL pour utiliser MPFR dans Panoramic mais l'antivirus m'empêche d'utiliser l'éditeur Panoramic !
Voici toujours le code de la DLL :
Code:
' PanoMPFR.bas : DLL pour utiliser MPFR dans Panoramic ' Compiler avec FBCroco ' Documentation : dans l'editeur FBCroco : ' Ctrl-F1 --> Calcul en multiprecision --> Evaluateur d'expressions mathematiques
#compile -dllpano
' Nombre de chiffres requis set_mpfr_prec 100
' Retourne le nombre de chiffres
function get_precision%() return get_mpfr_prec() end_function
' Initialisation (obligatoire) ' Retourne le nombre de fonctions utilisables = 40
function init_eval%() return SEE_InitEval() end_function
' Affectation de variable ("a".."z", majuscule ou minuscule) uniquement) ' Ex. set_variable("a", "1234.56789") ' Retourne le numero de la variable (a = 1 etc.)
function set_variable%(variable$, valeur$) return SEE_SetVariable(variable, valeur) end_function
' Calcul d'une expression mathematique ' Retourne un code d'erreur (voir doc. FBCroco)
function eval%(expression$, resultat$) return SEE_Eval(expression$, resultat$) end_function
Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
Sujet: Re: Comment déterminer le nombre de chiffres d'un nombre naturel Jeu 16 Nov 2023 - 13:30
Pour éviter le problème de l'antivirus avec l'éditeur Panoramic, utilise ELIP (disponible sur le forum). Ecrit entièrement en Panoramic, il est parfait. Je n'utilise plus que ça...
papydall
Nombre de messages : 7017 Age : 74 Localisation : Moknine (Tunisie) Entre la chaise et le clavier Date d'inscription : 03/03/2012
Sujet: Re: Comment déterminer le nombre de chiffres d'un nombre naturel Jeu 16 Nov 2023 - 13:58
Bonjour tout le monde.
@ jean_debord
J'ai compilé PanoMPFR.dll avec FBCroco sans problème. Je l'ai testé avec ce code en Panoramic
Code:
rem ============================================================================ dll_on "PanoMPFR.dll"
print " Nombre de fonctions : " ; dll_call0("init_eval") : ' Retourne le nombre de fonctions utilisables = 40 print " Nombre de chiffres : " ; dll_call0("get_precision") : ' Retourne le nombre de chiffres
dll_off rem ============================================================================
Voici le résultat
Ma question est : Comment l'utiliser pour effectuer des calculs, ... ?
Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
Sujet: Re: Comment déterminer le nombre de chiffres d'un nombre naturel Jeu 16 Nov 2023 - 14:05
Voici une capture avec HugeInteger de KGF.dll. Opération: 2 ^^200 => 61 chiffres !
jean_debord
Nombre de messages : 1266 Age : 70 Localisation : Limoges Date d'inscription : 21/09/2008
Sujet: Re: Comment déterminer le nombre de chiffres d'un nombre naturel Jeu 16 Nov 2023 - 15:54
papydall a écrit:
Ma question est : Comment l'utiliser pour effectuer des calculs, ... ?
Il faut lancer init_eval comme tu l'as fait puis mettre l'expression à évaluer dans une chaîne de caractères et récupérer le résultat dans une autre chaîne.
Voici un exemple (non testé car je n'ai pas encore installé ELIP) :
Code:
dim expr$, result$, n%
result$ = space$(110) ' Dimensionner à un peu plus que le nombre de chiffres requis
Nombre de messages : 1266 Age : 70 Localisation : Limoges Date d'inscription : 21/09/2008
Sujet: Re: Comment déterminer le nombre de chiffres d'un nombre naturel Ven 17 Nov 2023 - 9:33
Voici une version améliorée de la DLL. Il y a une fonction supplémentaire get_result qui fournit le résultat du dernier calcul, sous forme d'une chaîne de caractères formatée (un peu comme le printf du langage C).
Code:
' PanoMPFR : DLL pour utiliser MPFR dans Panoramic ' Compiler avec FBCroco ' Documentation : dans l'editeur FBCroco : ' Ctrl-F1 --> Calcul en multiprecision --> Evaluateur d'expressions mathematiques
#compile -dllpano
' Nombre de chiffres requis set_mpfr_prec 200
' Dernier resultat calcule dim result!
' Retourne le nombre de chiffres function get_precision%() return get_mpfr_prec() end_function
' Initialisation (obligatoire) ' Retourne le nombre de fonctions utilisables = 40 function init_eval% return SEE_InitEval() end_function
' Affectation de variable ("a".."z", (majuscule ou minuscule) uniquement) ' Ex. set_variable("a", "1234.56789") ' Retourne le numero de la variable (a = 1 etc.) function set_variable%(variable$, valeur$) return SEE_SetVariable(variable, valeur) end_function
' Calcul d'une expression mathematique ' Retourne un code d'erreur (voir doc. FBCroco) function eval%(expression$) return SEE_Eval(expression, result) end_function
' Recupere le resultat sous forme de chaine de caracteres ' fmt = format "%n.mF" ou "%n.mE" ' n, m = nb de chiffres avant et apres le point decimal ' F = notation en virgule flottante (123.45) ' E = notation exponentielle (1.2345E+2) ' La fonction retourne la longueur de la chaîne function get_result%(resultat$, fmt$) resultat = mpfr_to_str(result, fmt) return len(resultat) end_function
Je n'ai toujours pas pu tester. Même avec ELIP l'antivirus élimine le fichier Make_exe.
Yannick aime ce message
jean_debord
Nombre de messages : 1266 Age : 70 Localisation : Limoges Date d'inscription : 21/09/2008
Sujet: Re: Comment déterminer le nombre de chiffres d'un nombre naturel Lun 20 Nov 2023 - 11:23
J'ai pu finalement faire fonctionner l'éditeur Panoramic ainsi que ELIP sur un autre ordinateur... ce qui m'a permis de corriger un bug dans la précédente version de la DLL.
Celle-ci devrait fonctionner :
Code:
' PanoMPFR : DLL pour utiliser MPFR dans Panoramic ' Compiler avec FBCroco ' Documentation : dans l'editeur FBCroco : ' Ctrl-F1 --> Calcul en multiprecision --> Evaluateur d'expressions mathematiques
#compile -dllpano
' Nombre de chiffres requis set_mpfr_prec 200
' Dernier resultat calcule dim result!
' Retourne le nombre de chiffres function get_precision%() return get_mpfr_prec() end_function
' Initialisation (obligatoire) ' Retourne le nombre de fonctions utilisables = 40 function init_eval% return SEE_InitEval() end_function
' Affectation de variable "a".."z", (majuscule ou minuscule) ' Retourne le numero de la variable (a = 1 etc.) function set_variable%(variable$, valeur$) dim x! x = *p_valeur return SEE_SetVariable(variable, x) end_function
' Calcul d'une expression mathematique ' Retourne un code d'erreur (voir doc. FBCroco) function eval%(expression$) return SEE_Eval(expression, result) end_function
' Recupere le resultat sous forme de chaine de caracteres ' fmt$ = chaine de format sous la forme "%m.nF" ' m = nb de chiffres avant le point decimal ' n = nb de chiffres apres le point decimal ' pour forcer la notation scientifique, remplacer F par E function get_result%(resultat$, fmt$) *p_resultat = mpfr_to_str(result, fmt) return len(*p_resultat) end_function
Nombre de messages : 1266 Age : 70 Localisation : Limoges Date d'inscription : 21/09/2008
Sujet: Re: Comment déterminer le nombre de chiffres d'un nombre naturel Jeu 23 Nov 2023 - 16:41
Nouvelle version de la DLL. Celle-ci élimine les zéros non significatifs dans la réponse.
Code:
' PanoMPFR : DLL pour utiliser MPFR dans Panoramic ' Compiler avec FBCroco ' Documentation : dans l'editeur FBCroco : ' Ctrl-F1 --> Calcul en multiprecision --> Evaluateur d'expressions mathematiques
#compile -dllpano
' Nombre de chiffres requis set_mpfr_prec 200
' Dernier resultat calcule dim result!
' Retourne le nombre de chiffres function get_precision%() return get_mpfr_prec() end_function
' Initialisation (obligatoire) ' Retourne le nombre de fonctions utilisables = 40 function init_eval% return SEE_InitEval() end_function
' Affectation de variable "a".."z", (majuscule ou minuscule) ' Retourne le numero de la variable (a = 1 etc.) function set_variable%(variable$, valeur$) dim x! x = *p_valeur return SEE_SetVariable(variable, x) end_function
' Calcul d'une expression mathematique ' Retourne un code d'erreur (voir doc. FBCroco) function eval%(expression$) return SEE_Eval(expression, result) end_function
' Recupere le resultat sous forme de chaine de caracteres ' fmt$ = chaine de format sous la forme "%m.nF" ' m = nb de chiffres avant le point decimal ' n = nb de chiffres apres le point decimal ' pour forcer la notation scientifique, remplacer F par E function get_result%(resultat$, fmt$)
var p = 0 var suf = "" var res = mpfr_to_str(result, fmt) var sci = (upper(right(fmt,1)) = "E")
if sci then p = instr(upper(res), "E") suf = right(res, len(res) - p + 1) res = left(res, p - 1) end_if
res = rtrim(res, "0") res = rtrim(res, ".")
if sci then res = res + suf *p_resultat = res return len(res) end_function
Et un exemple, avec des sous-programmes pour les appels de DLL :
Code:
dll_on "PanoMPFR.dll"
dim variable$, valeur$, expr$, res$, fmt$
init_eval()
variable$ = "a" valeur$ = "1.23456789" set_variable(variable$, valeur$)
' ************************************************************* ' Sous-programmes (peuvent être placés dans un fichier INCLUDE) ' *************************************************************
Nombre de messages : 2747 Date d'inscription : 13/09/2009
Sujet: Re: Comment déterminer le nombre de chiffres d'un nombre naturel Sam 25 Nov 2023 - 17:37
Klaus a écrit:
Pour éviter le problème de l'antivirus avec l'éditeur Panoramic, utilise ELIP (disponible sur le forum). Ecrit entièrement en Panoramic, il est parfait. Je n'utilise plus que ça...
Je ne suis pas tellement d'accord. J'ai transformé tous mes exe-panoramic en exe-elip avec certains, l'antivirus les laisse passer, mais d'autres non, en particulier les raccourcis ! (voir par exemple le raccourci pour chants d'oiseaux)
Code:
rem ' Raccourci pour Chants-d'oiseaux if dir_exists("Chants-d'oiseaux")=1 dir_change "Chants-d'oiseaux" end_if execute_wait "Chants-d'oiseaux.exe" terminate
(Voici le bas du programme exe)
jjn4
Nombre de messages : 2747 Date d'inscription : 13/09/2009
Sujet: Re: Comment déterminer le nombre de chiffres d'un nombre naturel Mar 28 Nov 2023 - 14:44
Autant pour moi. Je m'étais servi d'une version d'Élip que j'avais sous la main, qui n'était pas la dernière version. Je viens d'essayer avec Élip-6.06 et effectivement, l'antivirus ne le pourchasse plus ! Super ! Merci, Marc.
jean_debord
Nombre de messages : 1266 Age : 70 Localisation : Limoges Date d'inscription : 21/09/2008
Sujet: Re: Comment déterminer le nombre de chiffres d'un nombre naturel Mer 20 Déc 2023 - 9:23
Nouvelle version de la DLL, pour FBCroco 0.42 :
Code:
' PanoMPFR : DLL pour utiliser MPFR dans Panoramic ' Compiler avec FBCroco ' Documentation : dans l'editeur FBCroco : ' Ctrl-F1 --> Calcul en multiprecision --> Evaluateur d'expressions mathematiques
#compile -dllpano
' Nombre de chiffres requis set_mpfr_prec 200
' Dernier resultat calcule dim result!
' Retourne le nombre de chiffres function get_precision%() return get_mpfr_prec() end_function
' Initialisation (obligatoire) ' Retourne le nombre de fonctions utilisables = 40 function init_eval% return SEE_InitEval() end_function
' Affectation de variable "a".."z", (majuscule ou minuscule) ' Retourne le numero de la variable (a = 1 etc.) function set_variable%(variable$, valeur$) dim x! x = *p_valeur return SEE_SetVariable(variable, x) end_function
' Calcul d'une expression mathematique ' Retourne un code d'erreur (voir doc. FBCroco) function eval%(expression$) return SEE_Eval(expression, result) end_function
' Recupere le resultat sous forme de chaine de caracteres ' fmt$ = chaine de format sous la forme "%m.nF" ' m = nb de chiffres avant le point decimal ' n = nb de chiffres apres le point decimal ' pour forcer la notation scientifique, remplacer F par E function get_result%(resultat$, fmt$)
dim res$, sci&, p%, suf$
res = mpfr_to_str(result, fmt) sci = (upper(right(fmt,1)) = "E")
if sci then p = instr(upper(res), "E") suf = right(res, len(res) - p + 1) res = left(res, p - 1) end_if
variable$ = "a" valeur$ = "100" set_variable(variable$, valeur$)
expr$ = "a" calc(expr$)
expr$ = "2^a" calc(expr$)
expr$ = "(2^a)^(1/a)" calc(expr$)
expr$ = "cos(a)^2 + sin(a)^2" calc(expr$)
expr$ = "cosh(a)^2 - sinh(a)^2" calc(expr$)
end
' ************************************************************* ' Sous-programmes d'appel de la DLL ' Peuvent être placés dans un fichier INCLUDE ' *************************************************************
fnc get_precision%() result dll_call0("get_precision") end_fnc