OVH Cloud OVH Cloud

[débutant] "Exception en point flottant"

11 réponses
Avatar
Dudule
Bonsoir,

Voici le code d'une application simple, pour appliquer l'apprentissage des
fonctions. Le programme a pour but de séparer les chiffres d'un entier.
La toute dernière instruction empêche l'exécution, et est à l'origine du
message figurant en sujet.

Merci pour votre aide.

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

unsigned short int quotient(unsigned short int, unsigned short int);
unsigned short int reste(unsigned short int, unsigned short int);
void affichage(unsigned short int);

int main()
{
int nombre;
do
{
cout << "Entrez un entier entre 1 et 32767: ";
cin >> nombre;
} while (nombre<=0 || nombre>=32768);

affichage(nombre);

return 0;
}

unsigned short int quotient(unsigned short int nombre, unsigned short int
diviseur)
{
return nombre/diviseur;
}

unsigned short int reste(unsigned short int nombre, unsigned short int
diviseur)
{
return nombre%diviseur;
}

void affichage(unsigned short int nombre)
{
unsigned short int diviseur=10000;
unsigned short int quot;


for (int i=5; i>=0; i--)
{
quot = quotient(nombre,diviseur);
if (quot!=0)
cout << quot << " ";
nombre = reste(nombre,diviseur);

/******** ligne à problème !! ********/
diviseur /= 10;
}
}

1 réponse

1 2
Avatar
kanze
Pierre Maurette wrote:
Dudule, le 10/05/2005, a écrit :[...]
Effectivement...
Mais le problème n'apparaît alors qu'à la dernière
itération. Pourquoi les autres itérations
n'effectuent-elles par leur cout ? Cela m'aurait sans doute
mis sur la voie (je pensais que j'avais un problème de
typage, avec ce message abscons).


(je suis très mauvais sur le "cout")


Mais les même règles s'appliquent à tous les filebuf.
(Professionnellement, chez moi, « cout » est prèsque toujours
dirigé vers "/dev/null". Donc, je ne m'en sers pas beaucoup.
Mais je connais un peu les ostream et les filebuf.)

cout envoie ses trucs vers un flux de sortie associé au
périphérique standard stdout,


Un flux de sortie associé aux sorties standard. C'est le même
périphérique que celui associé à stdout ; ce n'est pas le même
flux, mais les flux cout et stdout sont synchronisés.

l'écran de la console dans votre cas. Ce flux est tamponné
(bufférisé, buffered), c'est à dire qu'il ne se videra vers le
périphérique que ... quand il le voudra (honnêtement, je suis
un peu flou là dessus).


Les conditions sont néaumoins assez bien précisées : quand il
veut (typiquement, parce que le tampon est plein), ou quand tu
lui dis de le faire (fonction ostream::flush).

On va dire en fin de ligne,


Pas en fin de ligne. Tout le but du buffer, c'est que le
filebuf ne régarde même pas les caractères qu'on y met.

donc vous auriez pu faire:

cout << quot << endl;


Là, d'accord. Parce que endl est un manipulateur qui fait
l'équivalent de :

cout << 'n' ;
cout.flush() ;

à la place de
cout << quot << " ";
(bien sûr, le réultat n'est pas le même). Vous auriez
également pu écrire:

cout << quot << " ";
fflush(stdout);


Je ne crois pas. Ce n'est pas garanti, de toute façon, et ça ne
marche pas avec la plupart des implémentations. Un fflush sur
stdout n'a aucun effet sur cout (de même que cout.flush() n'a
aucun effet sur stdout).

Sauf, peut-être, à cause de la synchronisation particulière.
Mais ce n'est pas une règle générale pour les ostream ; pour
vider le tampon d'un ostream, on appelle une fonction sur
l'ostream.

Mais il ne s'agit là que de modification du code pour tracer,
comme vous auriez pu ajouter des cin, des system("PAUSE")
(DOS/Windows), etc.


Pourquoi faire. J'ai travaillé dans la passée sous MS-DOS, et je
ne connais pas « system( "PAUSE" ) ». De même pour le peu que je
fais sous Windows (dans une fenêtre CygWin avec bash -- ce n'est
probablement pas typique).

La vraie solution, c'est le débogueur.


La vraie solution, c'est d'apprendre à analyser ce qu'on fait. À
penser aux conditions de borne automatiquement.

C'est vrai que sous Linux, c'est assez rustique :-( .


Comment ça ? Je dirais que s'il faut ajouter quelque chose de
non-standard, comme « system( "PAUSE" ) », pour pouvoir lire ce
qu'on a écrit, c'est assez rustique.

Je crois que c'est limité à GDB. J'ai essayé DDD, qui enjolive
GDB, bon ... Mais un simpe débogueur source (et plus si
affinités) est un outil pédagogoque irremplaçable. J'admets
qu'il présente un petit danger, celui de faire en sorte que ça
marche, sans se préoccuper de la norme.


Surtout, celui d'écrire n'importe quoi, avec l'espoir qu'on se
ratrappera avec le deboggueur.

Tu rémarqueras que dans l'industrie, l'utilisation du déboggueur
se limite à peu près à des poste mortum ; l'analyse des core
dump. (Sur le dernier projet sur lequel j'ai travaille, il n'y
avait même pas de déboggueur installé sur les machines.)

[...]
En fait, je ne vois pas très bien pourquoi une fonction. A
part le fait d'écrire quotient et reste, qui peut en être une
très bonne.


En général, certes. Dans ce cas précis, en revanche...

En C++, quotient s'écrit « / », et reste s'écrit « % ». C'est
l'orthographe auquel s'attend tout programmeur C/C++. A priori,
si on l'orthographe différemment, c'est qu'il fait quelque chose
de différent.

Ceci dit, c'est clair que ce n'est pas un programme
professionnel. Sans y avoir pensé plus loin, je supposais que le
but des fonctions ici, c'était d'utiliser des fonctions, c-à-d
de s'exercer à définir des fonctions, et à les appeler. Alors,
pourquoi pas.

Il peut y en avoir une autre, en partie due à cette
cochonnerie d'opérateur /, qui mélange division euclidienne et
division réelle. Et là, effectivement, la fonction n'est pas
équivalent à l'opérateur seul:


Les siennes l'étaient. Mais c'est vrai que la division est mal
définie sur les entiers négatifs -- on ne s'en sert directement
que dans les cas où on sait que toutes les valeurs sont
positives (ou zéro pour le nominateur).

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


1 2