Bonjour à tous,
avec le code suivant, je m'attends à obtenir "-1" comme résultat.
#include <stdio.h>
int main(int argc, char** argv)
{
unsigned long long b = 5;
signed long long a = -5;
signed long long c = a / b;
printf("%llin", c);
return 0;
}
Or j'obtiens 3689348814741910322. La plateforme que j'utilise pour faire
ce test est Ubuntu Linux Lucid Lynx sur architecture x86_64.
# uname -a
Linux cervelet 2.6.32-25-generic #44-Ubuntu SMP Fri Sep 17 20:05:27 UTC
2010 x86_64 GNU/Linux
# gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Compilé sans optimisation. Est ce que je me trompe ? Ou est ce GCC qui
fait des bétises ?
Merci d'avance,
Yann
Bonjour à tous,
avec le code suivant, je m'attends à obtenir "-1" comme résultat.
#include <stdio.h>
int main(int argc, char** argv)
{
unsigned long long b = 5;
signed long long a = -5;
signed long long c = a / b;
printf("%llin", c);
return 0;
}
Or j'obtiens 3689348814741910322. La plateforme que j'utilise pour faire
ce test est Ubuntu Linux Lucid Lynx sur architecture x86_64.
# uname -a
Linux cervelet 2.6.32-25-generic #44-Ubuntu SMP Fri Sep 17 20:05:27 UTC
2010 x86_64 GNU/Linux
# gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Compilé sans optimisation. Est ce que je me trompe ? Ou est ce GCC qui
fait des bétises ?
Merci d'avance,
Yann
Bonjour à tous,
avec le code suivant, je m'attends à obtenir "-1" comme résultat.
#include <stdio.h>
int main(int argc, char** argv)
{
unsigned long long b = 5;
signed long long a = -5;
signed long long c = a / b;
printf("%llin", c);
return 0;
}
Or j'obtiens 3689348814741910322. La plateforme que j'utilise pour faire
ce test est Ubuntu Linux Lucid Lynx sur architecture x86_64.
# uname -a
Linux cervelet 2.6.32-25-generic #44-Ubuntu SMP Fri Sep 17 20:05:27 UTC
2010 x86_64 GNU/Linux
# gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Compilé sans optimisation. Est ce que je me trompe ? Ou est ce GCC qui
fait des bétises ?
Merci d'avance,
Yann
Indépendamment du plaisir purement intellectuel de discourir sur les
pièges du C, j'aimerais bien savoir dans quel cas , dans la "vraie vie",
on a réellement besoin du code présenté et pourquoi on ne pourrait faire
autrement.
Indépendamment du plaisir purement intellectuel de discourir sur les
pièges du C, j'aimerais bien savoir dans quel cas , dans la "vraie vie",
on a réellement besoin du code présenté et pourquoi on ne pourrait faire
autrement.
Indépendamment du plaisir purement intellectuel de discourir sur les
pièges du C, j'aimerais bien savoir dans quel cas , dans la "vraie vie",
on a réellement besoin du code présenté et pourquoi on ne pourrait faire
autrement.
Le 11-10-2010, Wykaaa a écrit :Indépendamment du plaisir purement intellectuel de discourir sur les
pièges du C, j'aimerais bien savoir dans quel cas , dans la "vraie vie",
on a réellement besoin du code présenté et pourquoi on ne pourrait faire
autrement.
typedef struct {
int *val;
size_t size;
} vector;
Ensuite, tu fais une moyenne (somme en int, divisée par la taille,
size_t).
Toute la question est: est-ce qu'on code les cardinaux, les tailles,
sur des int ou des non signés ? Et comment on fait avec str* et
malloc, calloc, qui prennent des non signés ?
Marc Boyer
Le 11-10-2010, Wykaaa <wykaaa@yahoo.fr> a écrit :
Indépendamment du plaisir purement intellectuel de discourir sur les
pièges du C, j'aimerais bien savoir dans quel cas , dans la "vraie vie",
on a réellement besoin du code présenté et pourquoi on ne pourrait faire
autrement.
typedef struct {
int *val;
size_t size;
} vector;
Ensuite, tu fais une moyenne (somme en int, divisée par la taille,
size_t).
Toute la question est: est-ce qu'on code les cardinaux, les tailles,
sur des int ou des non signés ? Et comment on fait avec str* et
malloc, calloc, qui prennent des non signés ?
Marc Boyer
Le 11-10-2010, Wykaaa a écrit :Indépendamment du plaisir purement intellectuel de discourir sur les
pièges du C, j'aimerais bien savoir dans quel cas , dans la "vraie vie",
on a réellement besoin du code présenté et pourquoi on ne pourrait faire
autrement.
typedef struct {
int *val;
size_t size;
} vector;
Ensuite, tu fais une moyenne (somme en int, divisée par la taille,
size_t).
Toute la question est: est-ce qu'on code les cardinaux, les tailles,
sur des int ou des non signés ? Et comment on fait avec str* et
malloc, calloc, qui prennent des non signés ?
Marc Boyer
Marc Boyer a écrit :Le 11-10-2010, Wykaaa a écrit :Indépendamment du plaisir purement intellectuel de discourir sur les
pièges du C, j'aimerais bien savoir dans quel cas , dans la "vraie vie",
on a réellement besoin du code présenté et pourquoi on ne pourrait faire
autrement.
typedef struct {
int *val;
size_t size;
} vector;
Ensuite, tu fais une moyenne (somme en int, divisée par la taille,
size_t).
Ton exemple est assez pertinent mais il me semble que celui-ci devrait
n'utiliser que des non signés.
Marc Boyer a écrit :
Le 11-10-2010, Wykaaa <wykaaa@yahoo.fr> a écrit :
Indépendamment du plaisir purement intellectuel de discourir sur les
pièges du C, j'aimerais bien savoir dans quel cas , dans la "vraie vie",
on a réellement besoin du code présenté et pourquoi on ne pourrait faire
autrement.
typedef struct {
int *val;
size_t size;
} vector;
Ensuite, tu fais une moyenne (somme en int, divisée par la taille,
size_t).
Ton exemple est assez pertinent mais il me semble que celui-ci devrait
n'utiliser que des non signés.
Marc Boyer a écrit :Le 11-10-2010, Wykaaa a écrit :Indépendamment du plaisir purement intellectuel de discourir sur les
pièges du C, j'aimerais bien savoir dans quel cas , dans la "vraie vie",
on a réellement besoin du code présenté et pourquoi on ne pourrait faire
autrement.
typedef struct {
int *val;
size_t size;
} vector;
Ensuite, tu fais une moyenne (somme en int, divisée par la taille,
size_t).
Ton exemple est assez pertinent mais il me semble que celui-ci devrait
n'utiliser que des non signés.
Le 11-10-2010, Wykaaa a écrit :Marc Boyer a écrit :Le 11-10-2010, Wykaaa a écrit :Indépendamment du plaisir purement intellectuel de discourir sur les
pièges du C, j'aimerais bien savoir dans quel cas , dans la "vraie vie",
on a réellement besoin du code présenté et pourquoi on ne pourrait faire
autrement.
typedef struct {
int *val;
size_t size;
} vector;
Ensuite, tu fais une moyenne (somme en int, divisée par la taille,
size_t).
Ton exemple est assez pertinent mais il me semble que celui-ci devrait
n'utiliser que des non signés.
Ben non, si on a des données potentiellement négatives (des températures
par exemple), il faut stocker des signés.
Marc Boyer
Le 11-10-2010, Wykaaa <wykaaa@yahoo.fr> a écrit :
Marc Boyer a écrit :
Le 11-10-2010, Wykaaa <wykaaa@yahoo.fr> a écrit :
Indépendamment du plaisir purement intellectuel de discourir sur les
pièges du C, j'aimerais bien savoir dans quel cas , dans la "vraie vie",
on a réellement besoin du code présenté et pourquoi on ne pourrait faire
autrement.
typedef struct {
int *val;
size_t size;
} vector;
Ensuite, tu fais une moyenne (somme en int, divisée par la taille,
size_t).
Ton exemple est assez pertinent mais il me semble que celui-ci devrait
n'utiliser que des non signés.
Ben non, si on a des données potentiellement négatives (des températures
par exemple), il faut stocker des signés.
Marc Boyer
Le 11-10-2010, Wykaaa a écrit :Marc Boyer a écrit :Le 11-10-2010, Wykaaa a écrit :Indépendamment du plaisir purement intellectuel de discourir sur les
pièges du C, j'aimerais bien savoir dans quel cas , dans la "vraie vie",
on a réellement besoin du code présenté et pourquoi on ne pourrait faire
autrement.
typedef struct {
int *val;
size_t size;
} vector;
Ensuite, tu fais une moyenne (somme en int, divisée par la taille,
size_t).
Ton exemple est assez pertinent mais il me semble que celui-ci devrait
n'utiliser que des non signés.
Ben non, si on a des données potentiellement négatives (des températures
par exemple), il faut stocker des signés.
Marc Boyer
Yann Renard a écrit :Bonjour à tous,
avec le code suivant, je m'attends à obtenir "-1" comme résultat.
#include <stdio.h>
int main(int argc, char** argv)
{
unsigned long long b = 5;
signed long long a = -5;
signed long long c = a / b;
printf("%llin", c);
return 0;
}
Or j'obtiens 3689348814741910322. La plateforme que j'utilise pour
faire ce test est Ubuntu Linux Lucid Lynx sur architecture x86_64.
# uname -a
Linux cervelet 2.6.32-25-generic #44-Ubuntu SMP Fri Sep 17 20:05:27
UTC 2010 x86_64 GNU/Linux
# gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Compilé sans optimisation. Est ce que je me trompe ? Ou est ce GCC qui
fait des bétises ?
Merci d'avance,
Yann
Indépendamment du plaisir purement intellectuel de discourir sur les
pièges du C, j'aimerais bien savoir dans quel cas , dans la "vraie vie",
on a réellement besoin du code présenté et pourquoi on ne pourrait faire
autrement.
Pour ma part, quand j'utilise un langage (n'importe lequel), je ne
mélange jamais des types différents dans une même expression, je n'ai
jamais eu le besoin de le faire car c'est un problème qui relève de la
conception.
Si on est obligé de caster et de convertir à tout va dans le code c'est
que la conception est foireuse, tout simplement.
Conclusion :
Par plaisir purement intellectuel, on peut discuter du code présenté
mais j'affirme que celui-ci est inutile car il n'y a pas de cas, dans la
réalité, où on serait forcé d'écrire ce code et rien d'autre...
Cependant, vous dites qu'il s'agit d'un test. C'est un test qui a quel
objectif ? Si c'est un test pour "voir" ce que ça fait sur votre
plateforme, il est inutile puisque dans une vraie application, on ne
rencontrera jamais le cas sauf à mal coder ou mal concevoir. C'est donc
de l'énergie dépensée pour rien.
Ce test n'est nécessaire que pour tester un compilateur (c'était mon
activité principale de faire des compilateurs, dont un compilateur C)
qui aurait été développé pour cette plateforme, mais je constate que ce
n'est pas le cas puisqu'il s'agit du gcc.
PS : désolé de "débouler" dans la discussion comme un chien dans un jeu
de quilles mais je rentre tout juste de l'hôpital où j'ai subi une
opération assez importante.
Yann Renard a écrit :
Bonjour à tous,
avec le code suivant, je m'attends à obtenir "-1" comme résultat.
#include <stdio.h>
int main(int argc, char** argv)
{
unsigned long long b = 5;
signed long long a = -5;
signed long long c = a / b;
printf("%llin", c);
return 0;
}
Or j'obtiens 3689348814741910322. La plateforme que j'utilise pour
faire ce test est Ubuntu Linux Lucid Lynx sur architecture x86_64.
# uname -a
Linux cervelet 2.6.32-25-generic #44-Ubuntu SMP Fri Sep 17 20:05:27
UTC 2010 x86_64 GNU/Linux
# gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Compilé sans optimisation. Est ce que je me trompe ? Ou est ce GCC qui
fait des bétises ?
Merci d'avance,
Yann
Indépendamment du plaisir purement intellectuel de discourir sur les
pièges du C, j'aimerais bien savoir dans quel cas , dans la "vraie vie",
on a réellement besoin du code présenté et pourquoi on ne pourrait faire
autrement.
Pour ma part, quand j'utilise un langage (n'importe lequel), je ne
mélange jamais des types différents dans une même expression, je n'ai
jamais eu le besoin de le faire car c'est un problème qui relève de la
conception.
Si on est obligé de caster et de convertir à tout va dans le code c'est
que la conception est foireuse, tout simplement.
Conclusion :
Par plaisir purement intellectuel, on peut discuter du code présenté
mais j'affirme que celui-ci est inutile car il n'y a pas de cas, dans la
réalité, où on serait forcé d'écrire ce code et rien d'autre...
Cependant, vous dites qu'il s'agit d'un test. C'est un test qui a quel
objectif ? Si c'est un test pour "voir" ce que ça fait sur votre
plateforme, il est inutile puisque dans une vraie application, on ne
rencontrera jamais le cas sauf à mal coder ou mal concevoir. C'est donc
de l'énergie dépensée pour rien.
Ce test n'est nécessaire que pour tester un compilateur (c'était mon
activité principale de faire des compilateurs, dont un compilateur C)
qui aurait été développé pour cette plateforme, mais je constate que ce
n'est pas le cas puisqu'il s'agit du gcc.
PS : désolé de "débouler" dans la discussion comme un chien dans un jeu
de quilles mais je rentre tout juste de l'hôpital où j'ai subi une
opération assez importante.
Yann Renard a écrit :Bonjour à tous,
avec le code suivant, je m'attends à obtenir "-1" comme résultat.
#include <stdio.h>
int main(int argc, char** argv)
{
unsigned long long b = 5;
signed long long a = -5;
signed long long c = a / b;
printf("%llin", c);
return 0;
}
Or j'obtiens 3689348814741910322. La plateforme que j'utilise pour
faire ce test est Ubuntu Linux Lucid Lynx sur architecture x86_64.
# uname -a
Linux cervelet 2.6.32-25-generic #44-Ubuntu SMP Fri Sep 17 20:05:27
UTC 2010 x86_64 GNU/Linux
# gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Compilé sans optimisation. Est ce que je me trompe ? Ou est ce GCC qui
fait des bétises ?
Merci d'avance,
Yann
Indépendamment du plaisir purement intellectuel de discourir sur les
pièges du C, j'aimerais bien savoir dans quel cas , dans la "vraie vie",
on a réellement besoin du code présenté et pourquoi on ne pourrait faire
autrement.
Pour ma part, quand j'utilise un langage (n'importe lequel), je ne
mélange jamais des types différents dans une même expression, je n'ai
jamais eu le besoin de le faire car c'est un problème qui relève de la
conception.
Si on est obligé de caster et de convertir à tout va dans le code c'est
que la conception est foireuse, tout simplement.
Conclusion :
Par plaisir purement intellectuel, on peut discuter du code présenté
mais j'affirme que celui-ci est inutile car il n'y a pas de cas, dans la
réalité, où on serait forcé d'écrire ce code et rien d'autre...
Cependant, vous dites qu'il s'agit d'un test. C'est un test qui a quel
objectif ? Si c'est un test pour "voir" ce que ça fait sur votre
plateforme, il est inutile puisque dans une vraie application, on ne
rencontrera jamais le cas sauf à mal coder ou mal concevoir. C'est donc
de l'énergie dépensée pour rien.
Ce test n'est nécessaire que pour tester un compilateur (c'était mon
activité principale de faire des compilateurs, dont un compilateur C)
qui aurait été développé pour cette plateforme, mais je constate que ce
n'est pas le cas puisqu'il s'agit du gcc.
PS : désolé de "débouler" dans la discussion comme un chien dans un jeu
de quilles mais je rentre tout juste de l'hôpital où j'ai subi une
opération assez importante.
Le 11-10-2010, Wykaaa a écrit :Marc Boyer a écrit :Le 11-10-2010, Wykaaa a écrit :Indépendamment du plaisir purement intellectuel de discourir sur les
pièges du C, j'aimerais bien savoir dans quel cas , dans la "vraie vie",
on a réellement besoin du code présenté et pourquoi on ne pourrait faire
autrement.
typedef struct {
int *val;
size_t size;
} vector;
Ensuite, tu fais une moyenne (somme en int, divisée par la taille,
size_t).
Ton exemple est assez pertinent mais il me semble que celui-ci devrait
n'utiliser que des non signés.
Ben non, si on a des données potentiellement négatives (des températures
par exemple), il faut stocker des signés.
Marc Boyer
Le 11-10-2010, Wykaaa<wykaaa@yahoo.fr> a écrit :
Marc Boyer a écrit :
Le 11-10-2010, Wykaaa<wykaaa@yahoo.fr> a écrit :
Indépendamment du plaisir purement intellectuel de discourir sur les
pièges du C, j'aimerais bien savoir dans quel cas , dans la "vraie vie",
on a réellement besoin du code présenté et pourquoi on ne pourrait faire
autrement.
typedef struct {
int *val;
size_t size;
} vector;
Ensuite, tu fais une moyenne (somme en int, divisée par la taille,
size_t).
Ton exemple est assez pertinent mais il me semble que celui-ci devrait
n'utiliser que des non signés.
Ben non, si on a des données potentiellement négatives (des températures
par exemple), il faut stocker des signés.
Marc Boyer
Le 11-10-2010, Wykaaa a écrit :Marc Boyer a écrit :Le 11-10-2010, Wykaaa a écrit :Indépendamment du plaisir purement intellectuel de discourir sur les
pièges du C, j'aimerais bien savoir dans quel cas , dans la "vraie vie",
on a réellement besoin du code présenté et pourquoi on ne pourrait faire
autrement.
typedef struct {
int *val;
size_t size;
} vector;
Ensuite, tu fais une moyenne (somme en int, divisée par la taille,
size_t).
Ton exemple est assez pertinent mais il me semble que celui-ci devrait
n'utiliser que des non signés.
Ben non, si on a des données potentiellement négatives (des températures
par exemple), il faut stocker des signés.
Marc Boyer
le cas dans lequel j'ai eu besoin de faire cela dans la vraie vie est
simple : je calcule la moyenne d'une série de valeurs entières signées,
stockées dans une std::vector (c'est du C++ mais je te présente mon cas
précis ;) ). Je fais donc simplement la somme de tous les éléments
contenus dans le vecteur et je divise par le .size() qui est
malheureusement non signé.
le cas dans lequel j'ai eu besoin de faire cela dans la vraie vie est
simple : je calcule la moyenne d'une série de valeurs entières signées,
stockées dans une std::vector (c'est du C++ mais je te présente mon cas
précis ;) ). Je fais donc simplement la somme de tous les éléments
contenus dans le vecteur et je divise par le .size() qui est
malheureusement non signé.
le cas dans lequel j'ai eu besoin de faire cela dans la vraie vie est
simple : je calcule la moyenne d'une série de valeurs entières signées,
stockées dans une std::vector (c'est du C++ mais je te présente mon cas
précis ;) ). Je fais donc simplement la somme de tous les éléments
contenus dans le vecteur et je divise par le .size() qui est
malheureusement non signé.
Le 12/10/2010 09:56, Yann Renard a écrit :le cas dans lequel j'ai eu besoin de faire cela dans la vraie vie est
simple : je calcule la moyenne d'une série de valeurs entières signées,
stockées dans une std::vector (c'est du C++ mais je te présente mon cas
précis ;) ). Je fais donc simplement la somme de tous les éléments
contenus dans le vecteur et je divise par le .size() qui est
malheureusement non signé.
Question bête: la moyenne n'étant de toute façon pas entière, pourquoi
ne pas convertir le total en double avant la division? Le résultat
serait un nombre flottant qui a beaucoup plus de sens pour la moyenne
qu'un nombre entier. (Quelle est la moyenne d'une mesure 0 ou 1 en entier?).
Le 12/10/2010 09:56, Yann Renard a écrit :
le cas dans lequel j'ai eu besoin de faire cela dans la vraie vie est
simple : je calcule la moyenne d'une série de valeurs entières signées,
stockées dans une std::vector (c'est du C++ mais je te présente mon cas
précis ;) ). Je fais donc simplement la somme de tous les éléments
contenus dans le vecteur et je divise par le .size() qui est
malheureusement non signé.
Question bête: la moyenne n'étant de toute façon pas entière, pourquoi
ne pas convertir le total en double avant la division? Le résultat
serait un nombre flottant qui a beaucoup plus de sens pour la moyenne
qu'un nombre entier. (Quelle est la moyenne d'une mesure 0 ou 1 en entier?).
Le 12/10/2010 09:56, Yann Renard a écrit :le cas dans lequel j'ai eu besoin de faire cela dans la vraie vie est
simple : je calcule la moyenne d'une série de valeurs entières signées,
stockées dans une std::vector (c'est du C++ mais je te présente mon cas
précis ;) ). Je fais donc simplement la somme de tous les éléments
contenus dans le vecteur et je divise par le .size() qui est
malheureusement non signé.
Question bête: la moyenne n'étant de toute façon pas entière, pourquoi
ne pas convertir le total en double avant la division? Le résultat
serait un nombre flottant qui a beaucoup plus de sens pour la moyenne
qu'un nombre entier. (Quelle est la moyenne d'une mesure 0 ou 1 en entier?).
Marc Boyer a écrit :Le 11-10-2010, Wykaaa a écrit :Marc Boyer a écrit :Le 11-10-2010, Wykaaa a écrit :Indépendamment du plaisir purement intellectuel de discourir sur les
pièges du C, j'aimerais bien savoir dans quel cas , dans la "vraie vie",
on a réellement besoin du code présenté et pourquoi on ne pourrait faire
autrement.
typedef struct {
int *val;
size_t size;
} vector;
Ensuite, tu fais une moyenne (somme en int, divisée par la taille,
size_t).
Ton exemple est assez pertinent mais il me semble que celui-ci devrait
n'utiliser que des non signés.
Ben non, si on a des données potentiellement négatives (des températures
par exemple), il faut stocker des signés.
Il suffit d'effectuer une translation par rapport à la plus petite
valeur. Et ceci est valable pour autre chose que des températures. Quand
on "normalise" des valeurs, la plupart du temps on effectue des
homothéties/translations (par exemple en assurance qualité logicielle).
Marc Boyer a écrit :
Le 11-10-2010, Wykaaa <wykaaa@yahoo.fr> a écrit :
Marc Boyer a écrit :
Le 11-10-2010, Wykaaa <wykaaa@yahoo.fr> a écrit :
Indépendamment du plaisir purement intellectuel de discourir sur les
pièges du C, j'aimerais bien savoir dans quel cas , dans la "vraie vie",
on a réellement besoin du code présenté et pourquoi on ne pourrait faire
autrement.
typedef struct {
int *val;
size_t size;
} vector;
Ensuite, tu fais une moyenne (somme en int, divisée par la taille,
size_t).
Ton exemple est assez pertinent mais il me semble que celui-ci devrait
n'utiliser que des non signés.
Ben non, si on a des données potentiellement négatives (des températures
par exemple), il faut stocker des signés.
Il suffit d'effectuer une translation par rapport à la plus petite
valeur. Et ceci est valable pour autre chose que des températures. Quand
on "normalise" des valeurs, la plupart du temps on effectue des
homothéties/translations (par exemple en assurance qualité logicielle).
Marc Boyer a écrit :Le 11-10-2010, Wykaaa a écrit :Marc Boyer a écrit :Le 11-10-2010, Wykaaa a écrit :Indépendamment du plaisir purement intellectuel de discourir sur les
pièges du C, j'aimerais bien savoir dans quel cas , dans la "vraie vie",
on a réellement besoin du code présenté et pourquoi on ne pourrait faire
autrement.
typedef struct {
int *val;
size_t size;
} vector;
Ensuite, tu fais une moyenne (somme en int, divisée par la taille,
size_t).
Ton exemple est assez pertinent mais il me semble que celui-ci devrait
n'utiliser que des non signés.
Ben non, si on a des données potentiellement négatives (des températures
par exemple), il faut stocker des signés.
Il suffit d'effectuer une translation par rapport à la plus petite
valeur. Et ceci est valable pour autre chose que des températures. Quand
on "normalise" des valeurs, la plupart du temps on effectue des
homothéties/translations (par exemple en assurance qualité logicielle).