| Probleme division d'entier | |
|
|
Auteur | Message |
---|
Nardo26
Nombre de messages : 2294 Age : 56 Localisation : Valence Date d'inscription : 02/07/2010
| Sujet: Probleme division d'entier Ven 25 Mar 2011 - 16:42 | |
| bonjour, En créant une petite fonction de conversion de code binaire naturel en code Gray, je me suis aperçu d'un "petit" problème sur la division d'un entier. exemple: - Code:
-
dim i% i% = 3 / 2 print i% on obtient 2 !!! C'est un tout petit peu gênant... Ce problème existe au moins depuis la version 0.9.19 du 17 juin ... (je ne sais pas avant...) | |
|
| |
Yannick
Nombre de messages : 8635 Age : 53 Localisation : Bretagne Date d'inscription : 15/02/2010
| Sujet: re Ven 25 Mar 2011 - 17:33 | |
| Tu lui reproches de te donner ce que tu lui demandes ! tu demandes un entier " i%" il te donne "2" l'entier approché avec "i" il devrait te donner "1.5" perso, je n'utilise plus que des réels pour les calculs et je n'arrondi pas le résultat, je limite l'affichage à 2 chiffre après la virgule à un résultat stocké au préalable dans une variable.cela me permet de repartir du résultat avec un nombre le plus près possible de la réalité. ( bon, je suis en surchauffe, je vais chercher un aspro ) | |
|
| |
Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: Probleme division d'entier Ven 25 Mar 2011 - 17:37 | |
| Nardo26, la division de deux réels donne un réel qui sera arrondi selon les règles habituelles au moment du dépôt dans un entier. Ainsi, 3/2 donne 1,5 qui sera arrondi logiquement à 2. tu aurais 2,9/2 qui donne 1,45 qui serait arrondi à 1.
Pour faire ce que tu veux faire, il faut utiliser la fonction INT() de Panoramic: i% = int(3/2) donne bien 1 et non 2 !
| |
|
| |
Yannick
Nombre de messages : 8635 Age : 53 Localisation : Bretagne Date d'inscription : 15/02/2010
| Sujet: re Ven 25 Mar 2011 - 19:30 | |
| Aurais je été à côté de la plaque dans ma réponse maître Klaus ? | |
|
| |
Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: Probleme division d'entier Ven 25 Mar 2011 - 22:03 | |
| @ygeronimi: non, pas du tout ! Tu as dit fort justement que Panoramic faisait exactement ce qu'on lui demandait. Mais je voulais aller plus loin. Le but de mon post, c'était de montrer la solution avec la fonction int() en faisant la comparaison entre cette fonction et l'arrondi pratiqué lors du transfert dans un entier. | |
|
| |
Nardo26
Nombre de messages : 2294 Age : 56 Localisation : Valence Date d'inscription : 02/07/2010
| Sujet: Re: Probleme division d'entier Ven 25 Mar 2011 - 23:22 | |
| Tu as raison oui et non : tu as raison si j'écris : i=int(3/2) mais dans le cas de l'écriture de : i%=entier1%/entier2% ma fonction int est implicite. pourquoi devrais-je préciser que je veux la partie entière avec la fonction int alors que la variable de destination est un int ? Je sais bien qu'en interne le calcul est réalisé avec des flottants mais l'analyseur syntaxique devrait appliquer systématiquement un int() strict - et non pas un trunc(), round ou autres joyeusetés de ce genre - dans le cas d'une affectation dans un entier. Je me trompe ? Si en C j'écris : unsigned i; i=3/2; Je vais bien obtenir 1 et non pas 2 : le compilo va me faire un décalage vers la droite. il n'y a pas reste, d'arrondi ou quoique ce soit qui rentre en jeux... on travaille avec un entier, point final. il y a une ambiguïté dans la manière dont les int sont traités sous Panoramic. En fait ce sont de faux int... c'est un non-sens, c'est comme si je m"amusai à recaster en C un truc dans ce genre : unsigned i,j; i=3; j=2; i = (unsigned)((unsigned)i / (unsigned)j); ou si je pousse à l'extreme ma simple division par 2 devient : *(unsigned *)&i /= *(unsigned*)&j; /* là il ne reste plus qu'a se taper la tête contre un mur */ Klaus, tu parles de la division de 2 reels, ok mais si j'écris ceci : - Code:
-
dim i%,j% i%=3 j%=2 i%= i%/j% print i% j'obtiens 2... et dans ce cas on a précisé à la division que nous avons à faire à des int... si j'ecris : i%=int(i%/j%) j'ai l'impression de bégayer... non ? | |
|
| |
Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: Probleme division d'entier Ven 25 Mar 2011 - 23:47 | |
| Non, tout est normal. Il ne faut pas oublier qu'il faut comparer à Delphi, pas à C. Les constantes 3 et 2 sont converties en valeurs flottantes, et l'affectation à un entier DOIT être faite via la fonction TRUNC ou ROUND. Voici un petit code Delphi qui le montre (tu places un bouton dans form1 et tu copies ce code dans l'évènement click du bouton): - Code:
-
unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Déclarations privées } public { Déclarations publiques } end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); var i,k: integer; j: extended; begin j := 3/2; i := round(j); k := trunc(j); showmessage(format('j=%f i=%d k=%d',[j,i,k])); end;
end.
Tu ne peux pas faire j := 3/2 ==> erreur de compilation ! Tel que Panoramic est fait, la fonction ROUND est utilisée d'office pour placer le résultat de n'importe quel calcul dans un entier. Si tu veux autre chose, il faut explicitement appeler TRUNC. | |
|
| |
Nardo26
Nombre de messages : 2294 Age : 56 Localisation : Valence Date d'inscription : 02/07/2010
| Sujet: Re: Probleme division d'entier Sam 26 Mar 2011 - 0:00 | |
| Oui je vois ce que tu veux dire mais hors langage de programmation, mathématiquement parlant ce n'est pas logique. Je sais pas mais si je prend un papier et un crayon et que je pose ma division, je vais obtenir 1 et non pas 2. (même avec la méthode de cosmos ! ) 3/2 = 1.5 ok, quand j"était au primaire on m'a appris que la partie entiere de 1.5 c'etait 1. A moins que les maths ont changées depuis ? Je ne demande pas l'entier le plus proche mais juste la partie entière de 1.5. C'est ce résultat que normalement je devrais obtenir lorsque j'affecte 3/2 dans une variable de type entier. PS : Je ne suis même pas sûr que trunc renverrai tout le temps le bon résultat.
Dernière édition par Nardo26 le Sam 26 Mar 2011 - 0:12, édité 1 fois | |
|
| |
Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: Probleme division d'entier Sam 26 Mar 2011 - 0:10 | |
| Crois-moi: Panoramic est défini de sorte que l'affectation dans un entier se fait TOUJOURS comme ceci: - Code:
-
i% = ROUND(expression) Si tu ne veux que la partie entière, il faut ajouter INT en Panoramic, ce qui est traduit ainsi: - Code:
-
i% = ROUND(TRUNC(expression)) Ca n'a rien avoir avec la vue intuitive que 2 n'est contenu qu'une seule fois dans 3. En Panoramic, les constantes entières n'existent pas, tout simplement. Le seul moment où l'on a vraiment une représentation binaire sur 32 bits d'un entier, c'est dans la zone de stockage en mémoire d'une variable déclarée avec le fameux % en Panoramic. Jack pourrait sûrement donner plus de détails, mais il est même possible qu'une instruction comme - Code:
-
i% = j% passe par une valeur flottante intermédiaire. Comme il n'y a pas d'arithmétique entière en Panoramic, il n'y a aucune raison de gérer des valeurs temporaires en représentation entière. Tout doit être converti automatiquement en flottant, et l'affectation à un entier doit se faire automatiquement via un ROUND, sans considérer la vraie valeur à affecter. Et en ce qui concerne TRUNC en Delphi (soit INT en Panoramic), ça marche toujours. EDIT Remplace la ligne - Code:
-
i := 3/2; par - Code:
-
j := 2.999999999/2; j et k sont affichés égal à 1, et i est affiché égal à 1,50. Pourquoi ? parce que le format donne deux décimales par défaut, et l'arrondi se fait donc à 1,50. Mais la ligne suivante montre la vrais situation: - Code:
-
showmessage(format('j=%15.11f i=%d k=%d',[j,i,k]));
Dernière édition par Klaus le Sam 26 Mar 2011 - 0:17, édité 1 fois | |
|
| |
Yannick
Nombre de messages : 8635 Age : 53 Localisation : Bretagne Date d'inscription : 15/02/2010
| Sujet: bref Sam 26 Mar 2011 - 0:14 | |
| ben en Panoramic il faut ecrire : - Code:
-
dim i% i%=int(3/2) print i%
pour obtenir 1 | |
|
| |
Invité Invité
| Sujet: Re: Probleme division d'entier Sam 26 Mar 2011 - 0:22 | |
| Ce qui manque à Panoramic, est une définition de départ. Les deux façons de voir sont valables. On est en basic, et les définitions ne sont pas forcément les même que dans un autre langage. Je ne pouvais pas faire de comparaison avec JustBasic, celui-ci n'a pas de variable entière. Je viens de faire l'essai sur le basic de mon Palm (Ybasic) et la j'obtiens le résultat de 1. J'a tellement vu de basics différents sur les autres machines, que j'ai pris le principe de travailler selon les possibilités de ceux-ci. Maintenant c'est à Jack de dire ce qu'il pense. Maintenant il me semble que Jack a dit dans le sujet "je ne sais plus faire une addition", que les calculs étaient fait sur des entiers D'ailleurs voilà ce qu'il dit: - Citation :
- Dans PANORAMIC, tous les calculs s'effectuent en réel, même les calculs avec des entiers. Ainsi, lorsqu'on affecte dans une variable entière le résultat d'un calcul, on a le maximum de précision.
Pour cela, une conversion du résultat en entier est effectué pour affecter un nombre entier dans une variable entière. Pour cette raison, mes programmes maintenant, je diminue l'emploi des entiers. Pourquoi faire? |
|
| |
Nardo26
Nombre de messages : 2294 Age : 56 Localisation : Valence Date d'inscription : 02/07/2010
| Sujet: Re: Probleme division d'entier Sam 26 Mar 2011 - 0:23 | |
| ok, je crois qu'on tourne en rond: Ce que je veux dire c'est que l'opération : i%=ROUND(TRUNC(expression)) devrais être systématique dès que la variable de destination est de type entier. Mathématiquement parlant cela me parait plus juste... Cela ne modifie pas grand chose dans mon prog de rajouter un int(). Mais rajouter des int() de partout quand on ne travaille qu'avec des entiers n'est pas naturel. Ou alors il ne faut plus utiliser les variables de type entier et ne passer que par des reels. mais dans ce cas on peut se poser la question : quel est l'interet des variables de type entier en Panoramic ? | |
|
| |
Invité Invité
| Sujet: Re: Probleme division d'entier Sam 26 Mar 2011 - 9:27 | |
| Personnellement, j'ai été surpris aussi. J'ai déjà eu ce problème, et j'ai du faire une formule avec int( pour obtenir le résultat attendu. Je ne suis jamais entré dans le fait que c'était un bug, il n'y a pas de définition de départ pour expliquer que la partie entière n'est pas tronquée, mais que c'est seulement la représentation d'un entier (enfin vous comprenez ce que je veux dire).
Là ou je ne suis pas d'accord, il y a eu plusieurs interventions pour demander des explications. Je cite tout de mémoire, mais l'idée est vrai. Quelle est la différence entre une variable avec"%" et une autre. Nous avons répondu (mais je crois que c'est Klaus) qu'une variable entière était (toujours de mémoire) tronquée de la partie décimal. Il y a eu d'autre question, et c'était toujours sur le même principe. Nous y avons répondu, et Jack a laissé faire sans nous dire que nous étions dans le faut. On a l'air malin ensuite lorsque l'on fait des réponses qui devraient être juste, mais ne correspondent pas à la réalité. Jack ne veut pas donner d'information sur la conception de son basic. Plus d'une fois j'ai posé tel ou tel question sur le basic, et je suis resté sans réponse. Tenez un exemple: à quoi peut bien servir NUMBER_EVENTS. J'ai eu une réponse, mais qui ne me servait pas. Ayant constaté par exemple que l'on pouvait plus de 5000 le nombre d'évènements. Q'avec une boucle de repeat/until avec un return à l'intérieur on diminuait ce nombre. J'ai demandé des éclaircissements, sans réponse. Il y en a plein comme cela. Alors que Jack intervient sur des petits sujets que l'on peut traité. Il y a un certain nombre de question qui sont resté sans réponse. Désolé Jack, mais sur ce forum, je ne triche pas. Lorsque quelque chose me plait, je le dis. Lorsque quelqu'un me semble dans l'erreur, je le dis aussi. Cela ne signifie pas qu'il y a un problème avec toi. J'ai toujours considéré que c'était ton basic, et que tout t'appartient ici. Je te souhaite bon retour dans notre monde à problèmes. |
|
| |
jean_debord
Nombre de messages : 1266 Age : 70 Localisation : Limoges Date d'inscription : 21/09/2008
| Sujet: Re: Probleme division d'entier Sam 26 Mar 2011 - 11:04 | |
| Certains BASICs ont un opérateur "\" pour symboliser la division entière (équivalent de div en Pascal). Par exemple en FreeBASIC on aurait : - Code:
-
dim as integer i
i = 3 / 2 : print i ' imprime 2 i = 3 \ 2 : print i ' imprime 1
Cet opérateur manque à Panoramic (de même que le moins unaire). | |
|
| |
Contenu sponsorisé
| Sujet: Re: Probleme division d'entier | |
| |
|
| |
| Probleme division d'entier | |
|