OVH Cloud OVH Cloud

[Calcul] Problème étrange

69 réponses
Avatar
Rincevent
Bonjour à tous,
g un gros problème dans mon programme C++.
Voilà g 3 entier a,b et c
Je souhaite calculer la partie entière de (a/b)*c
J'utilise pour cela la fonction floor() de <cmath>
Or deux problèmes se présentent :

1) Le compilateur renvoie 0 lorsque je lui demande de calculer (a/b)*c (et
ce, alors que les valeurs de a,b,c ne devraient pas donner un tel résultat)

2) Le compilateur m'insulte lorsque j'essaie d'appliquer la fonction floor()
à (a/b)*c (motif : l'argument n'est pas un double...)


- Je suppose qu'il doit exister une fonction pour convertir des rapports
d'entier en double, non ?
- Et inversement pour passer d'un double codant un entier --> en type int ?
- floor() attend un double comme argument... Soit mais quel est le type duy
résultat ? un double ? un int ?
- comment résoudre cet épineux problème de façon élégante ??? ;-)

Quelqu'un peut-t-il m'aider ?
Merci d'avance !

Rincevent

9 réponses

3 4 5 6 7
Avatar
Alain Naigeon
a écrit dans le message news:


Ça dépend. Il existe un type double. Je m'en passe dans mes
applications, et je ne trouve pas ça bizarre ; il s'avère que mes
applications n'utilisent pas l'abstraction que double implémente.


Bien sûr. Je voulais dire "bizare", quand la sémantique est la bonne.

Ce qui importe, ce n'est pas le nom, mais ce qui est derrière.


Oui, mais le choix du nom est important.
Expérience de pensée : je fais une classe de matrices, avec une
fonction rendant une matrice diagonalisée. Tu t'en sers, jusqu'au
jour où tu obtiens des bêtises parce que tu as construit une
matrice non diagonalisable. Et je te réponds que ma fonction
ne vérifie pas si elle l'est. Tu penses quoi de mon travail ?

Et maintenant Mr X construit un type sans signe, muni de la
soustraction, et je m'en sers jusqu'au jour où 'obtiens n'importe
quoi parce que j'ai fait 5 - 8 ; et MrX me répond que... etc.
Eh bien, je pense de MrX la même chose que ci-dessus.

--

Français *==> "Musique renaissance" <==* English
midi - facsimiles - ligatures - mensuration
http://anaigeon.free.fr | http://www.medieval.org/emfaq/anaigeon/
Alain Naigeon - - Strasbourg, France

Avatar
Alain Naigeon
"Gabriel Dos Reis" a écrit dans le message
news:
"Alain Naigeon" writes:

[...]

| Ce n'est certainement pas une raison, à mes yeux, pour
| violer grossièrement le bon sens en permettant que le
| type d'un nombre d'habitants puisse être négatif.

Quel est le type de 180000, en C ou C++ ?


Evidemment j'ai fait une bévue en donnant l'exemple
mal choisi d'une donnée qui pouvait aller au-delà
de la limite du type ; et tu t'engouffre dans la brêche
avec un talent... inimitable, mais :

Je n'ai pas dit, jamais que tout devrait exister, tout fait
(même si, comme ta remarque le suggère, des grands
entiers "de base" seraient bienvenus, à mon point de
vue).
Ce que je voulais dire, c'est qu'on doit m'expliquer
pourquoi je ne devrais pas typer un nombre d'enfants
par un unsigned int.

(je ne néglige pas du tout la suite de ta réponse, mais
j'attends d'en avoir fait le tour avant de réagir).

--

Français *==> "Musique renaissance" <==* English
midi - facsimiles - ligatures - mensuration
http://anaigeon.free.fr | http://www.medieval.org/emfaq/anaigeon/
Alain Naigeon - - Strasbourg, France


| L'idée
| de bricoler des gardes-fous par des tests à l'exécution
| n'est qu'un pis aller, vraiment pas séduisante quand il
| existe un type qui colle avec le domaine de définition
| de ce qu'on veut représenter.
| Un nombre d'habitants est, par nature, non signé. Je




----------------------------------------------------------------------------
----



Ce n'est pas à un physicien que je vais dire cela, mais je crois tu
confonds implicitement un nombre avec unité avec simplemennt un
nombre. Il n'y a pas de nombre avec unité en C ou C++. Tu peux
introduire une classe en C++, si tu veux.




----------------------------------------------------------------------------
----



| choisis donc le type "unsigned int", qui signifie, si je
| ne m'abuse : "non signé". Donc, si quelque chose
| cloche par après, c'est la faute du langage, pas la
| mienne !




----------------------------------------------------------------------------
----



Non, c'est le tien : la syntaxe des types n'est pass tout.
Avec ton raisonnement, un débutnt qui pense qu'il a un calcul complexe
à faire sur le nombre d'habitant d'une ville devrait utiliser
complex<unsigned>.




----------------------------------------------------------------------------
----



| (en plus, ce n'est pas en me disant que ça vient du C
| qu'on va me convaincre, mais alors là pas du tout ;




----------------------------------------------------------------------------
----



que tu le veilles ou non, la compatibilité avec le C est un facteur
majeur. Stroustrup savait comment inventer un très beau langage
incompatible avec C. Beaucoup de gens ont fait/font ça, ils écrivent des
papiers académiques, puis ils en inventent d'autres, puis ils
vont faire autre chose.

[...]




----------------------------------------------------------------------------
----



| focntions, et par nostalgie je vais même l'appeler
| "this", pourquoi pas, hein ? :-) )




----------------------------------------------------------------------------
----



Et tu ne serais pas le premier. J'en connais plein qui vont ça tous
les jours :-)

-- Gaby



Avatar
Michel Michaud
Dans news:40b7bd0c$0$26904$, Alain
"Michel Michaud" a écrit dans le message news:
3Zltc.48920$
Dans news:c9470d$ohu$, Vincent
Je crois que je n'ai pas dit les choses correctement. En
disant « quand il en a besoin » je voulais dire « quand
c'est tout
ce dont il a besoin ». Si tu as absolument besoin de la
division entière, je suis sûr que tu la mettras puisque sinon
ton programme ne fonctionnera pas. Mais si la division
entière est suffisante (est tout ce dont tu as besoin),
alors que / (division réelle) fonctionne aussi, tu vas
vraiment penser à mettre ?


Comme ça, là, je ne vois pas de cas (hors les cas triviaux ou
on fait la division de deux entiers dont le dividende est un
multiple du diviseur) ou la division entière et la division
réelle ont des résultats équivalents.


Non, mais quand tu remets la valeur dans un entier oui !



Si c'est fait exprès par un cast, on en prend la responsabilité.
Sinon, on doit avoir "conversion may loose digits", non ?


Non, pas en VB où a= b/c avec tout en entier, fait une division
réelle puis reconvertit en entier sans rien dire. Et le
compilateur ne peut pas optimiser vraiment pour faire l'opération
en entier, en tout cas, pas dans des cas où le résultat serait
potentiellement, par exemple avec a= b/c + d/e par exemple.

Je continue à croire qu'en informatique, ce qui est normal
c'est de faire les opérations selon les types impliqués, à
moins de demander explicitement une conversion. En fait, je
vois que je suis plutôt contre toute conversion implicite qui
change quelque chose aux valeurs impliquées, dans n'importe
quel sens.

Ce qui explique peut-être aussi (je rejoins l'autre discussion)
pourquoi je suis d'accord de ne pas prendre des unsigned pour
simplement noter des valeurs qui ne sont pas négatives : lors
des opérations, il y a des conversions possibles et tout le
système logique s'effondre. C/C++ sont ainsi faits. S'il n'y
avait pas de conversion implicite, ce serait peut-être différent
(encore que j'aime bien penser que si j'ai (a-b > 0) j'aurai
aussi (a > b)).

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/




Avatar
Gabriel Dos Reis
"Alain Naigeon" writes:

| "Gabriel Dos Reis" a écrit dans le message
| news:
| > "Alain Naigeon" writes:
| >
| > | je ne suis réaliste, travaillons avec ce qu'offre le langage. Ce que je
| dis
| > | simplement, c'est que s'il existe un type, alors c'est vraiment bizare
| > | de s'en passer.
| >
| > Ce serait vraiment bizarre de se servir d'un type juste parce qu'il
| > existe non parce que sa sémantique convient.
|
| Je trouve que tu restes elliptique, et un peu coupeur de
| cheveux en quatre quand tu évoques la syntaxe à tout
| propos.

Pas du tout. Je pense que tu insistes sur unsigned parce que tu
traduis sa syntaxe par « non-signé » et tu en déduis que tu devrais
l'utiliser. Je pense que si on l'avait appeler fubar, tu auraiss
prêter un peu plus attention à sa sémantique.

| D'abord le langage commun fait partie de ce qui permet
| de communiquer ; même la norme est écrite en langage
| humain ;-) Donc, est-ce trop demander qu'un type
| appelé "entier" ait la sémantique des entiers ? Parce que
| si la réponse est non, alors j'en connais au moins un qui,
| en d'autres circonstances, aurait appelé ça de l'obfuscation.

Comme std::remove?

| Il me paraît tout de même important de marquer nettement,
| pour ceux qui le savent moins que toi, que les entiers
| pré-existent à l'informatique, et que si celle-ci propose un
| type qui en diffère subtilement, il est très maladroit de
| lui donner exactement le même nom.

Pas vraiment. Après tout, un nom désigne ce qu'on décide de lui donner
comme signification dans le contexte. Implacablement.

| Pour finir, cela me fait une belle jambe de savoir que la
| sémantique est diifférente, si je ne sais pas en quoi elle
| diffère.

Je crois que beaucoup de gens, dans ce thread, notamment James et Samy
te l'ont expliquée. Tu veux que je répète ce qu'ils sont dit ? :-)

-- Gaby
Avatar
Gabriel Dos Reis
"Alain Naigeon" writes:

| a écrit dans le message news:
|
|
| > Ça dépend. Il existe un type double. Je m'en passe dans mes
| > applications, et je ne trouve pas ça bizarre ; il s'avère que mes
| > applications n'utilisent pas l'abstraction que double implémente.
|
| Bien sûr. Je voulais dire "bizare", quand la sémantique est la bonne.
|
| > Ce qui importe, ce n'est pas le nom, mais ce qui est derrière.
|
| Oui, mais le choix du nom est important.
| Expérience de pensée : je fais une classe de matrices, avec une
| fonction rendant une matrice diagonalisée. Tu t'en sers, jusqu'au
| jour où tu obtiens des bêtises parce que tu as construit une
| matrice non diagonalisable. Et je te réponds que ma fonction
| ne vérifie pas si elle l'est. Tu penses quoi de mon travail ?

Quel est le rapport avec la choucroute ?

| Et maintenant Mr X construit un type sans signe, muni de la
| soustraction, et je m'en sers jusqu'au jour où 'obtiens n'importe
| quoi parce que j'ai fait 5 - 8 ; et MrX me répond que... etc.
| Eh bien, je pense de MrX la même chose que ci-dessus.

Bah

-- Gaby
Avatar
Gabriel Dos Reis
Gabriel Dos Reis writes:

| | Et maintenant Mr X construit un type sans signe, muni de la
| | soustraction, et je m'en sers jusqu'au jour où 'obtiens n'importe
| | quoi parce que j'ai fait 5 - 8 ; et MrX me répond que... etc.
| | Eh bien, je pense de MrX la même chose que ci-dessus.
|
| Bah

Bah non.

-- Gaby
Avatar
Pierre Maurette
typa:

[...]
Le problème, c'est ce qu'on entend par « division ». Si tu démandes à un
non-informaticien quelle est la valeur de 1/3, il va te dire un
tiers. Et non 0. Dans la mésure où l'opérateur ne donne pas 1/3, ou
quelque chose de proche, pour 1/3, je ne trouve pas que l'opérateur /
est bien choisi.

Ça ne veut pas dire que je suis contre la division entière, comme elle
est définie. Seulement le choix de l'opérateur. Si je concevais un
langage, sans tenir compte de l'historique, je ne définirais pas
l'opérateur / pour les entiers. Et je ne supporterais pas non plus des
conversions implicites : une expression du genre i / j, où i et j sont
des entiers, serait simplement illégal.

[...]

Tout à fait. Je trouve que l'utilisation d'un opérateur autre que / aide
à se rappeler que l'opération n'est pas celui auquel on pourrait
s'attendre.
Je réponds ici parce que vous parlez de la perception non informatique

de la division. Je suis en accord avec ce qui est écrit, je veux
simplement préciser.
Il y a intuitivement réellement deux types de divisions, la différence
ne se faisant pas sur le type des opérandes mais sur celui attendu du
ou des résultats.

[nota : j'utilise volontairement le mot "réel", là où j'aurais sans
doute du utiliser "fractionnaire"]

* La division entière : elle attend un quotient ENTIER et un reste,
réel dans le cas le plus général. Elle répond à la question "Combien
de FOIS va Qtté2 dans Qtté1, et que reste-t-il ?". Pour tous les types
d'opérandes, il est facile de donner un exemple intuitif dès l'école
primaire.
Combien puis-je remplir de bouteilles de 0,75 litre avec un tonnelet
de 10,25 litres ? 13 bouteilles, reste 0,50 litre.
Je note que le MOD de Excel fonctionne tout à fait dans ce sens (mais
pas de DIV sauf erreur de ma part sous Excel), mais pas celui de
Delphi.

* La division : elle n'attend qu'un résultat, le quotient, réel dans
le cas le plus général, qui se veut exact. Pour l'illustrer, il me
semble qu'il faut au moins un public qui admet que chaque ménage
français fait 1,73 enfant. Ou alors botter en touche, en expliquant
que 13,66666... bouteilles signifie 13 bouteilles et une pas tout à
fait remplie ;-)

En C/C++, en tenant compte des conversions, les deux opérations se
rejoignent dans le cas d'opérandes et d'un résultat entiers : le
quotient converti implicitement de la division :
a = (double)a / b;
est le même (le plus souvent, mais risque de différence si a % b == 0)
que le quotient de la division entière :
a = a / b;
Mais il me semble que c'est plutôt malheureux, bien que je m'en
satisfasse sans problème.
--
Pierre

Avatar
James Kanze
"Alain Naigeon" writes:

|> a écrit dans le message news:
|>

|> > Ça dépend. Il existe un type double. Je m'en passe dans mes
|> > applications, et je ne trouve pas ça bizarre ; il s'avère
|> > que mes applications n'utilisent pas l'abstraction que double
|> > implémente.

|> Bien sûr. Je voulais dire "bizare", quand la sémantique est la
|> bonne.

|> > Ce qui importe, ce n'est pas le nom, mais ce qui est derrière.

|> Oui, mais le choix du nom est important.

Je suis tout à fait d'accord. Malheureusement, pour des raisons
historiques, les noms en C++ ne sont pas toujours bien choisis. Le cas
de std::remove est flagrant, à mon avis, double est un peu trompeur
aussi, dans la mésure que ça doit être le type flottant par
défaut, et unsigned ne correspond pas trop à la sémantique du
type non plus.

|> Expérience de pensée : je fais une classe de matrices, avec
|> une fonction rendant une matrice diagonalisée. Tu t'en sers,
|> jusqu'au jour où tu obtiens des bêtises parce que tu as
|> construit une matrice non diagonalisable. Et je te réponds que ma
|> fonction ne vérifie pas si elle l'est. Tu penses quoi de mon
|> travail ?

Ça dépendrait du contexte historique. J'accepte bien qu'on a un
type dans certains langages qui s'appelle integer, bien qu'il est clair
qu'il n'accepte pas tous les entiers. A priori, un type qui s'appelle
Matrice, mais qui n'accepte que des matrices diagonales me semble
louche. Comme une fonction qui s'appelle std::remove qui ne fait que
changer l'ordre des éléments.

Dans le cas de unsigned, je n'ai pas d'idée fixe de ce que pourrait
être la conception mathématique derrière ce mot. Mais vue sa
sémantique, je trouve que quelque chose comme « modulo » serait
un meilleur nom.

|> Et maintenant Mr X construit un type sans signe, muni de la
|> soustraction, et je m'en sers jusqu'au jour où 'obtiens n'importe
|> quoi parce que j'ai fait 5 - 8 ; et MrX me répond que... etc. Eh
|> bien, je pense de MrX la même chose que ci-dessus.

Tout à fait:-). À part qu'autant que je sache, « unsigned »
n'est pas une abstraction mathématique dans le même sens que
matrice l'est.

--
James Kanze
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
Avatar
Gabriel Dos Reis
James Kanze writes:

[...]

| Dans le cas de unsigned, je n'ai pas d'idée fixe de ce que pourrait
| être la conception mathématique derrière ce mot. Mais vue sa
| sémantique, je trouve que quelque chose comme « modulo » serait
| un meilleur nom.

Yep, ou plus précisément « modular_integer », mais aucun programmeur C
n'accepterait (surtout dans les années '70) d'écrire un nom aussi
long :-) Peut-être « modi » à la rigueur :-)

-- Gaby
3 4 5 6 7