Bon voilà je me rends compte que j'ai besoin d'utiliser des nombres à virgule flottante
Donc je reprends des posts dans le topic "GTC prob type float" :
Zephyr (./55) :
C'est juste une convention, tu vas utiliser des entiers pour représenter des valeurs décimales, donc à toi de choisir combien de bits tu vas utiliser pour ta partie entière et ta partie décimale et d'effectuer les divisions au bon moment.
Pour être plus parlant, mettons que tu veux avoir deux coordonnées X et Y pour un objet, et tu veux que ces coordonnées soient des nombres décimaux. Tu peux par exemple dédier 3 bits pour la partie flottante (ce qui te fait une précision à 1/3^2 = 1/8 = 0.125 près, c'est pas top mais ça dépend pour quoi). Tu fais grosso modo tous tes calculs sans te soucier de ça, mais au moment d'afficher ton objet à l'écran par exemple, tu divises tes valeurs par 8 (= tu décales de 3 bits, c'est plus rapide) pour récupérer ce qui correspond à la partie entière dans ta représentation. De la même façon tu peux isoler les 3 derniers bits pour obtenir l'équivalent de la partie "après la virgule" de ta représentation.
Pour un pseudo-exemple de code, faute d'imagination voilà ce que ça pourrait donner :/* Je choisis de réserver 3 bits pour ma partie décimale */
x = 5 << 3; /* Je veux fixer x à 5.0, dans ma représentation il faut multiplier
par 3^2 : une valeur de 5 serait en fait équivalente dans ma représentation à
5 / 3^2 soit 0.625. */
y = 12 << 3; /* Idem */
while (53)
{
x += 1; /* Si l'on prend en compte le sens de ma représentation, ici je
n'ajoute pas 1 à x mais 1/3^2 donc "l'équivalent" de 0.125. Si j'avais
voulu ajouter 1, il aurait fallu ajouter 1 * 3^2 donc 8. */
putPixel (x >> 3, y >> 3); /* Je veux les parties entières de mes nombres
qui sont dans une représentation particulière, on dégage donc les 3 derniers
bits qui correspondent à la partie décimale. */}
[edit] Le résultat de ce bout de code serait que le pixel n'est visiblement déplacé qu'une fois tous les 8 tours de boucle. Tel quel ça n'a pas beaucoup d'interêt, mais par exemple dans un jeu ça peut permettre des écarts de vitesse bien plus fins (8 fois) qu'entre "mon objet se déplace de 1 en 1 pixels" et "mon objet se déplace de 2 en 2 pixels"; ici tu peux avoir un mobile qui se déplace en moyenne de 1.625 pixels par boucle, par exemple.
et
Brunni (./57) :tama (./54) :
je comprends pas
pourquoi faut diviser le nombre par 2^k ?
tu pourrais pas mettre un petit bout de code très rapide pour que j'y comprenne quelque chose ? ^^
En base 100, si tu as 350:
* 350 / 100 = 3 (division entière)
* 350 % 100 = 50 (% = modulo = reste de la division de 350 par 100)
Donc ça marche bien, par contre la division est très lente, et le modulo aussi. C'est pour ça qu'ils te proposent d'utiliser des décalages de bits.
Par exemple si tu prends le nombre 8 ça donne en binaire 1000. Si tu le décales d'un bit vers la droite ça donne 100, ce qui est 4. Ca réalise donc bien une division par 2 (pour chaque décalage), et c'est bcp plus rapide (plus facile de décaler les bits que faire une division, à la main aussi d'ailleurs). Mais comme on ne peut pas réaliser une division de 100 avec des puissances de 2 (2, 4, 8, ..., 64, 128, 256, ...), on choisit une autre valeur, par exemple 256 (ou plus ou moins selon la précision dont tu as besoin).
Pour le modulo on a le "AND" bit à bit, avec un masque qui ne garde que les derniers bits. Exemple:
* 3.5: 3 * 256 + 0.5 * 256 = 896 (0x380 en hexa)
* 896 >> 8 = 896 / 256 = 3 (division entière)
* 896 & 255 = 896 % 256 = 128
128 est la moitié de la base (256) donc ça donne bien 3.5
[Edit] Réellement désolé Zephyr, j'ai complètement zappé ton message(et une demie heure de perdue, une)
Maintenant le problème c'est, si par exemple je reprends ce que Brunni a dit et que je veux afficher 3.5 comment je passe de 128 à .5 ?