Bonjour,
pour m'exercer j'essaie de créer une classe u64 (unsigned codés sur 64 bits), en surchargeant les opérations sur cette classe:
mais si j'execute le code suivant:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 struct u64 { u32 faible; u32 fort; u64(u64 &right) { faible = right.faible; fort = right.fort; } // u32 -> u64 u64(u32 right) { faible = right; fort = 0; } u64& operator=(const u64 &right) { faible = right.faible; fort = right.fort; return (*this); } inline static void multiplie(const u32 left, const u32 right, u64 &result) { u32 a,b,c,d,i,j,k,l; a = left & 0xffff; b = ((u32)left) >> 16; c = right & 0xffff; d = ((u32)right) >> 16; i = a * c; j = a * d; k = b * c; l = b * d; j += k; if(j < k) l++; result.faible = i + (j << 16); // pas d'overFlow possible result.fort = l + (((u32)j) >> 16); // idem } // u64 -> u32 operator unsigned int const (void) { return faible; } }; u64 operator*(const u64 &left, const u64 &right) { u64 result; u64 i,j,k; u64::multiplie(left.faible,right.faible,result); if((left.fort) || (right.faible)) { u64::multiplie(left.fort,right.faible,j); u64::multiplie(left.faible,right.fort,k); result.fort += j.faible + k.faible; } return result; }
c vaut 0 !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 u64 a = 1 << 31; u64 b = 1 << 31; u64 c = a * b;
alors que ceci:
me renvoie bien le bon résultat 1 << 62.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 u64 a = 1 << 31; u64 b = 1 << 31; u64 c; c = a * b;
en step-by-step, on voit que dans le premier cas c'est l'opérateur de copie qui est utilisé, et pour une raison qui m'échappe, dans le second cas le compilo préfère caster le résultat de a * b en u32 puis lui appliquer le constructeur 32 bits u64(u32 right) plutôt que d'utiliser directement l'opérateur de copie 64 bits u64(u64 &right).
A noter que si j'enlève le code permettant le cast de u64 à u32, ou le constructeur 32 bits u64(u32 right), alors il utilise bien l'opérateur de copie 64 bits u64(u64 &right) et la valeur de c devient juste dans les 2 morceaux de codes ci-dessus.
D'où ma question: 1) commet expliquer au compilo que c'est bien l'opérateur de copie 64 bit qu'il doit utiliser dans ce cas, et pas le constructeur 32 bits ?
et 2) (question subsidiaire): est-ce que c'est possible de désactiver le cast implicite dans le code:
un peu dans le genre du mot clé explicit qu'on peut ajouter devant:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 operator unsigned int const (void) { return faible; }
puisque en principe on voudrait plutôt que l'utilisateur puisse faire librement des:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 explicit u64(u32 right) { faible = right; fort = 0; }
plutôt que des:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3u64 a; u32 b = 10; a = b;
(qui eux devraient générer une erreur sauf si on cast b = (u32)a; )
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 u64 a = 1 << 50; u32 b; b = a;
merci d'avance !
Partager