Page 1 sur 2
Problème de précision sur nombre saisi au clavier
Publié : ven. 11/déc./2015 22:57
par SULREN
Bonjour,
Préambule :
J’utilise PB depuis 2005, à ma grande satisfaction mais toujours pour du calcul scientifique (plutôt tordu) avec très peu d’imagerie. Je n’utilise donc qu’une infime, vraiment infime, partie du jeu d'instructions de PB.
Mais j’ai besoin de vitesse d’exécution parce que je fais essentiellement des calculs itératifs et j’ai presque toujours besoin d’une très grande précision sur les variables.
Je ne suis donc pas débutant en « terme d’ancienneté », mais débutant en « matière de programmation ».
Je suis en Windows 10, sur un PC assez puissant et avec disque SSD.
Le problème qui me fait demander votre aide et le suivant :
Pour un travail en cours actuellement, je dois saisir au clavier des nombres entiers qui peuvent être très grands, en restant toutefois dans les limites :
-9223372036854775808 à + 9223372036854775807
Quelquefois la valeur prise en compte par le programme n’est pas celle que j’ai saisie.
Exemple si je saisis 17 fois 1 : 11111111111111111
le programme travaille sur : 1111111111111111
2
et cela casse tout mon travail.
J’aimerais savoir à quel endroit je me plante dans les déclarations. Merci d’avance de votre aide.
Pour illustrer mon problème j’ai écrit un bout de code (V 5-40), en syntaxe infantile, sans subtilités, afin de ne pas brouiller les pistes, et avec des tas de commentaires.
Tant qu’on saisit moins de 17 chiffres il n’y a pas de problème, c’est au-delà que cela part en vrille.
Code : Tout sélectionner
;PROGRAMME DE TEST DE SAISIE EN QUAD DE NOMBRE TAPE AU CLAVIER
;*************************************************************
OpenConsole()
;Déclaration variable au format Quad
NOMBRE.q=0
QUOTIENT.d=0
;Saisie du nombre
Print("TAPER LE NOMBRE A SAISIR : ")
NOMBRE$=Input()
NOMBRE=Val(NOMBRE$) ;Ai pris Val() et pas ValD() ou ValF(), afin de saisir au format Quad
PrintN(" ")
;Print du nombre saisi au format Quad, puis Float
Affich1$=Str(NOMBRE) ;Pris Str() pour convertir un format Quad
PrintN("AFFICHAGE DE LA SAISIE en Quad: "+Affich1$)
Affich2$=StrD(NOMBRE,10)
PrintN("AFFICHAGE DE LA SAISIE en Float: "+Affich2$)
PrintN(" ")
;Division nombre par 2 et Print
QUOTIENT=NOMBRE/2
Affich3$=StrD(QUOTIENT)
PrintN("Resultat division NOMBRE par 2= "+Affich3$)
PrintN(" ")
;Quitter progrmamme
Repeat
PrintN("Pressez q ou Q pour quitter")
Rep2$=Input():PrintN(" ")
Until Rep2$="q" Or Rep2$="Q"
Inkey()
CloseConsole()
End
Re: Problème de précision sur nombre saisi au clavier
Publié : ven. 11/déc./2015 23:14
par falsam
En remplaçant Affich2$=StrD(NOMBRE,10) par Affich2$=StrU(NOMBRE,#PB_Quad) le résultat devrait être correct.
PS: Pourquoi un affichage en float ?
Re: Problème de précision sur nombre saisi au clavier
Publié : ven. 11/déc./2015 23:26
par SULREN
Merci pour ta réponse.
Mais la modif ne fait que résoudre le problème d'affichage, pas le problème de fond qui est que les calculs se font sur le nombre:
11111111111111112 au lieu de 11111111111111111
C'est pour cela que je fais la division par 2.
Mon programme fonctionnait bien jusqu'à présent mais aujourd'hui je suis tombé sur ce "foutu" nombre qui s'est transformé et les résultats étaient faux. Heureusement que je m'en suis aperçu.
Ensuite j'ai fait ce petit test d'affichage juste pour détecter pourquoi le nombre devient subitement divisible par 2....alors que je travaille sur des nombres supposés premiers.
EDIT: je n'ai pas répondu à ta question:
"Pourquoi un affichage en float ?"
Je n'en ai pas besoin dans mon programme de travail. J'ai juste utilisé cela dans le bout de programme de test pour essayer de visualiser les changement de valeur inopinés du nombre.
La division par deux montre bien que le nombre qui finissait pas ...111 lors de la saisie se finit par ...11
2 au moment où la division s'exécute.
PS:je fais de la factorisation, mais ce n'est pas pour casser des codes

Re: Problème de précision sur nombre saisi au clavier
Publié : ven. 11/déc./2015 23:42
par falsam
SULREN a écrit :Mais la modif ne fait que résoudre le problème d'affichage, pas le problème de fond qui est que les calculs se font sur le nombre:
11111111111111112 au lieu de 11111111111111111
Non j'obtiens bien 11111111111111111 au lieu de 11111111111111112
Re: Problème de précision sur nombre saisi au clavier
Publié : ven. 11/déc./2015 23:46
par SULREN
Si tu fais une division du nombre que tu as saisi par 2 tu obtiens un quotient avec un "6" à la fin ou un ".5"
Il me faut le ".5"
Si tu as 6 c'est que le nombre est devenu 11111111111111112
Re: Problème de précision sur nombre saisi au clavier
Publié : sam. 12/déc./2015 2:16
par Ar-S
Bon je suis une pine en math donc "pataper" si je dis une connerie.
Et si tu passes ton quotient en .q ?
Re: Problème de précision sur nombre saisi au clavier
Publié : sam. 12/déc./2015 9:19
par SULREN
Bonjour,
Ar-s:
Et si tu passes ton quotient en .q ?
Je ne peux pas faire cela, parce que je travaille sur un problème de factorisation.
Je prends un nombre entier par exemple : 11111111111111111 (soit 17 fois 1).
Je le divise par un entier, par exemple : 2
Je veux savoir si le quotient est un entier, et j’ai donc besoin
de le lire d’abord en Float:
Normalement je devrais trouver : 11111111111111111 / 2 = 555555555555555,5
Ce qui m’apporte l’évidence que le quotient n’est pas un entier.
Dans le bout de code que j’ai joint à mon premier post on voit que le programme me fait :
Nombre saisi au clavier……….………… : 11111111111111111
Nombre réellement pris en compte : 11111111111111112
Donc quotient : 555555555555556
Qui me fait croire que le quotient est un nombre entier……et c’est faux.
Tout se passe comme si on ne pouvait pas saisir plus de 16 chiffres, avec exactitude, alors que je pensais qu'on pouvait aller jusqu'à: 9223372036854775807
Je pense que j’utilise la bonne version de PB et que l’erreur (grossière) que je commets se situe ailleurs.
Je suis en V 5.40 LTS pour Windows-x64 et mon PC est en Windows x64 processeur x64
Re: Problème de précision sur nombre saisi au clavier
Publié : sam. 12/déc./2015 10:02
par Fig
A vu de nez, ton problème vient du format float. Tu devrais regarder sur wikipedia le nombre de chiffre représentatif (mantisse)...
En 32bits c'est 23 bits (soit environ 7 chiffres représentatifs)
et en 64 53 bits (soit environ 16 chiffres représentatif)
Avec tes 17 "1" d'affilé il y a évidemment un problème et un arrondit.
Je n'ai pas le temps de vérifier mais je suis sûr que tu peux le faire de ton coté.
https://fr.wikipedia.org/wiki/Virgule_flottante
Re: Problème de précision sur nombre saisi au clavier
Publié : sam. 12/déc./2015 10:31
par Micoute
Bonjour SULREN,
le problème ne vient pas de PureBasic, mais des microprocesseurs !
Re: Problème de précision sur nombre saisi au clavier
Publié : sam. 12/déc./2015 11:06
par SULREN
Bonjour Micoute,
le problème ne vient pas de PureBasic, mais des microprocesseurs !
Je crois en effet que tu viens d'écrire la phrase qui tue!
Le help de PureBasic dit que le format Quad permet d'aller de:
-9223372036854775808 à + 9223372036854775807
ce qui correspond bien à un nombre codé sur 64 bits (8 octets).
On garde un bit pour le signe et il en reste 63 pour la valeur du nombre, exprimé en entier, qui peut donc atteindre 2^63, c'est bien la valeur max donnée ci-dessus.
Mais il est bien possible que mon processeur Intel CORE i5, lui, ne travaille pas pleinement sur 64 bits, contrairement à ce qui est indiqué par le vendeur (ce ne sera pas la première fois qu'un vendeur triche, même les "Das Auto de WW" le font).
Je vais aller voir sur Gogol ce que ma "daube" de processeur sait réellement faire.
Puis je m'en sortir en utilisant la version de Pb pour 32 bits et en travaillant en double longueur? Mon processeur doit savoir manipuler du 32 bits, quand même....où sinon je le passe au pilon!
Je perdrais en vitesse d'exécution, mais faute de grives.........
Re: Problème de précision sur nombre saisi au clavier
Publié : sam. 12/déc./2015 14:27
par Fig
Dites, je suis à la limite d'être vexé là... Personne ne lit ce que j'écris ?
(Cf Précautions d'emploi de l'article Wikipédia...)
Un float est codé comme ceci:
signe+exposant+Mantisse
Sur un 64bit ça donne:
1 bit de signe, 11 bits pour l'exposant et
53 bits de mantisse.
"11111111111111111"D en décimal => en binaire "100111 01111001 01111111 00100110 11010110 01110001 11000111"B (soit
54 bits tiens tiens...)
Comme la mantisse est sur
53 bits ca donne donc: "100111 01111001 01111111 00100110 11010110 01110001 1100100" (le 0111 est tronqué en 011 et arrondi en 100)
Le dernier bit le moins significatif passe à la trappe, et on arrondis au dessus le reste pour en tenir compte..
Voila l'arrondis !
L'exposant est donc de "1" en binaire.
Une fois tronqué de la sorte, il est évident que en divisant par 2 (cad en effectuant un décalage d'un rang vers la droite du binaire) on obtient une valeur entière puisque le chiffre éjecté est un 0.
CQFD ??
En conclusion, le float n'est pas une panacée pour les calculs à moins de tenir compte de ses particularités. Ca n'a donc rien à voir avec votre processeur qui fonctionne très bien. (je peux m'être trompé ci-dessus mais c'est truc de ce genre en tout cas..)
Ps:Je viens d'expliquer à ma femme, elle me dit qu'elle a tout compris: "il a sa bite qui fait l'arrondit, le gars ? c'est ça ?"

Re: Problème de précision sur nombre saisi au clavier
Publié : sam. 12/déc./2015 15:12
par SULREN
Re bonjour Fig,
PRIMO : tu n’as pas de raisons de te vexer car j’avais bien lu ton premier post.
Je lis toujours les messages de ceux qui ont pris la peine de me répondre…..et d’autant plus quand je suis sur un problème qui me bloque.
SECUNDO : tu as bien raison de te vexer, parce qu’après avoir lu ton premier message je n’ai pas vu où je me faisais piéger.
P….. de vieillesse ! Voilà ce que c’est quand on arrive à 70 ans. On ne percute pas vite !
Même le cerveau fait l'arrondi.
Je n’ai pas retenu ta remarque du premier post parce que je travaille sur des entiers en Quad et pas sur des Float,
justement pour avoir le maximum de bits affectés à la résolution du nombre. Je connais depuis mes études supérieures (début des années 60) le codage en flottant qui n’affecte qu’une partie des bits à la mantisse.
Le problème est qu’à un moment, qui ne dure pas et que donc j'ai oublié, dans mon programme je suis obligé de passer en Float, juste le temps d'un test et cela me rabote de la résolution. Ensuite je reviens en Quad par IntQ()
Ce programme a bien marché, et je ne me suis rendu compte de rien, tant que je lui rentrais des nombres entiers de moins de 17 digits, ou qu'il y en avait plus mais que les calculs les ramenaient en dessous, avant que je passe par l'étape Float.
Mille Zexcuses à tous pour le temps que je vous ai fait perdre et merci pour votre aide.
Je vais demander à Frédéric L de servir une tournée générale.
Je vais surtout revoir l’analyse de mon programme pour rester en Quad tout le temps. Pas évident.....
PS : Juste avant de lire le message de Fig j’ai fait un test pour vérifier que mon processeur travaillait bien sur 64 bits.
J’ai rentré en Quad le nombre : 1111111111111111 soit 16 digits, juste à la limite de ce que je supposais être un problème.
Ensuite j’ai multiplié, toujours en Quad, ce nombre par 100 et j’ai ajouté 11. J'étais donc à 18 digits et qu'avec des 1.
Ensuite j’ai retiré 11 et j’ai divisé par 100.
J’ai imprimé le résultat et j’ai retrouvé le nombre de départ, preuve qu’il n’y a avait eu aucune perte de résolution dans les calculs en dépassant 16 digits.
Re: Problème de précision sur nombre saisi au clavier
Publié : sam. 12/déc./2015 15:32
par Fig
Effectivement le problème n'intervient que dans certains cas, pas à chaque fois qu'on est supérieur à 17 chiffres en décimal.
Je m'étonnais aussi que vous ne connaissiez pas le fonctionnement d'un float vu que vous effectuez des calculs mathématiques dont je serais sans doute incapable de comprendre même la nécessité.
Le fait que vous soyez passé à coté à cause, justement, de votre savoir en la matière est extrêmement classique et ça m'arrive souvent aussi.
J'ai le souvenir pas si lointain d'un algo de remplissage que j'avais codé où j'avais carrément oublié un morceau essentiel et trivial (sans lequel c'était trop lent)...
Mon cerveau passait au dessus de cette partie, comme si je l'avais déjà codé..
Il a fallu que Falsam y mette le nez pour le mettre en évidence.
C'est un peu humiliant, mais c'est la vie... parfois on cherche un crayon et on l'a sur son oreille.
C'est à ça que le forum sert, avoir un pt de vue extérieur ça débloque tout parfois.
Re: Problème de précision sur nombre saisi au clavier
Publié : sam. 12/déc./2015 16:57
par SULREN
Re,
C’est bon, je viens de modifier mon programme. Tout baigne. Je garde l’étape Float pour le test que j’ai à faire, mais je me garde bien de revenir au Quad par IntQ().
Je retrouve mon nombre Quad en ne faisant que des opérations sur des Quad.
J’ai commis une erreur que j’aurais pu éviter facilement en respectant une règle que je m’étais juré de toujours respecter, à savoir : de ne jamais « pisser » de code sans avoir écrit un minimum de document d’analyse.
Je respecte cette règle chaque fois que je dois écrire un programme compliqué, pour mes calculs d’horloges astronomiques, de mécanique céleste, de résolution d’équations non linéaires, etc.
L’expérience m’a prouvé que le temps qu’on y passe est toujours bien inférieur au temps qu’on perdrait en débuggage si on ne le faisait pas. De plus, on augmente les chances de partir dans la bonne direction pour son algorithme que si on se met à pianoter du code d’emblée.
Et il y a quelques jours, comme la nuit tombe vite et que les soirées sont longues, je me suis mis en tête d’écrire un petit programme de factorisation de nombres, dont j’avais besoin.
Le portable devant la télé pour écouter des débats tout en travaillant, devant la cheminée bien sûr car c’est plus sympa, et devant un petit verre de mirabelle (maison) pour vérifier quelle vieillissait bien.
Comme j’avais l’algorithme en tête, je me suis mis à aligner les instructions sans avoir écrit une petite analyse (c’est bon, c’est fastoche, on y va direct !!!!!). Elle m’aurait conduit à assurer la cohérence de résolution des nombres d’un bout à l’autre.
Conclusion : on ne s’assagit pas forcément en prenant de l’âge. On refait des bêtises qu’on s’était juré de ne plus jamais faire.
De même, hier soir, au lieu de demander de l’aide sur le forum, ce qui au demeurant est sympa aussi et permet d’aller constater avec plaisir qu’il vit toujours, j’aurais pu attendre le lendemain, avoir les idées plus claires et reprendre les choses méthodiquement.
Mais merci à tous again.
PS Je faisais du Fortran dans les années 60, sur un « calculateur » de la CII, un 9010 de mémoire. Le bon temps des cartes et des rubans perforés.
Mais je préférais à l’époque les calculatrices analogiques : elles résolvaient de façon naturelle les systèmes d'équations différentielles (idéal pour les études de dynamique des systèmes qui étaient mon domaine) et elles procuraient un plaisir de travail extraordinaire. Ceux qui les ont connues en garderont toujours la nostalgie. Si j’en trouvais une aux puces je l’achèterais sans hésiter.
Re: Problème de précision sur nombre saisi au clavier
Publié : sam. 12/déc./2015 17:27
par Marc56
Je me rappelle de mon étonnement il y a une quinzaine d'année: je devais faire un petit programme (script Perl) chargé de reprendre des données issues d'un programme de comptabilité (un truc en Cobol) pour faire des statistiques. Je n'y connais rien en Cobol mais le programmeur me mettait les sorties à traiter en fichier texte brut.
On m'avait dit: fait attention,
les montants sont toujours donnés en centimes! J'ai demandé pourquoi ? simple, pour ne pas s’embêter (avoir des emm...) avec les calculs en virgule flottante.
(Il y avait tout un tas de mécanismes internes chargés lors de divisions de s'occuper des dixièmes de centimes)
Les serveurs étaient peu puissants (par rapport à aujourd'hui) mais les analystes/programmeurs étaient rusés et logiques.
