1

En C et C++ pour caster une variable, on utilise :
float flottant = (float)entier;
En GLSL, le cast d'une variable se fait ainsi :
float flottant = float(entier);
La question est : POURQUOI NOUS FONT-ILS CHIER? C'était trop simple de causer dans un langage universel?
D'autant plus que la syntaxe de leur code est pompée, jusqu’à l'os, sur le C.

Je suis pourtant un fervent défenseur du C#, et donc des nouvelles habitudes surtout si elle sont nécessaires, mais là ils se foutent de la gueule du monde, non?

2

en flash c'est le même principe, très chiant aux premier abord, oui
et la le mec il le pécho par le bras et il lui dit '

3

Je n'ai pas parlé de Flash, mais j'y ai pensé très fort, je te l'accorde.
On s'y fait c'est vrai, quand ils nous donnent suffisamment d'outils pour caster proprement, ce qui est le cas de GLSL. Mais ça reste une décision con, dès le départ de prendre le contre-pied du C.

4

bah ils veulent peu être faire plus simple, pour un novice ca fait une chose de moins à apprendre,
et en l'occurrence une fonction à des entrée et une sortie, alors pkoi pas pour de la conversion ?
un peu comme atoi(), (int)machaine serais bien plus simple happy oula faut que jarrette le php moi cheeky
et la le mec il le pécho par le bras et il lui dit '

5

explication

float plop = (float) truc est un cast. on interprète truc comme un float puis on le met dans plop

float plop = float(truc) : ici truc est probablement un entier, on le donne en paramètre à une fonction qui a pour nom float et retourne un float.

ca arrive dans les langages qui n'ont pas de cast car leurs types sont plus stricts que le C.

6

Ou alors tu peux aussi voir float() comme appel d'un constructeur d'un "objet" de type float. Cette syntaxe existe en C++…
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

7

Si c'est dans une expression mathématique, il faut des parenthèses autour du truc à caster, et au final type(expression) est plus concis que (type)(expression). Et perso je trouve que c'est plus lisible, aussi.
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

8

GoldenCrystal (./6) :
Cette syntaxe existe en C++

Oui, tu peux adopter cette syntaxe en C++, mais on me l'avait déconseillé dans le topic où j'avais posé la question, je sais plus pourquoi.
Ceci dit, je trouve que la notation fonctionnelle se comprend naturellement.

9

Ou alors on revient à l'assembleur shader, hein...

Kochise
avatar
Si Dieu m'a de nouveau fait homme, cette fois il m'a pas raté : marcher sur l'eau et dupliquer les pains, ça marche p'us :/

10

GUNNM> bah, t'appelle in-place le constructeur du type float en lui passant un int. t'as la meme chose en C++ confus
au contraire, je trouve ca mieux..
avatar
HURRRR !

11

Edited_3981

12

Oui, tu peux adopter cette syntaxe en C++, mais on me l'avait déconseillé dans le topic où j'avais posé la question, je sais plus pourquoi.


hum
etrange, je vois pas pourquoi non plus. a la limite ca peut se comprendre si tu considere le cast de types qui sont des pointeurs ou des references, vu que float*(truc) ou float&(truc) n'est pas une syntaxe valide, alors que les parentheses pour les casts C-style fonctionnent universellement pour tous les types, mais de toutes facons pour les types pointeurs/refs, c'est pas plus mal de passer par les casts type-safe du C++
avatar
HURRRR !

13

squalyl (./5) :
explication

float plop = (float) truc est un cast. on interprète truc comme un float puis on le met dans plop

float plop = float(truc) : ici truc est probablement un entier, on le donne en paramètre à une fonction qui a pour nom float et retourne un float.

ca arrive dans les langages qui n'ont pas de cast car leurs types sont plus stricts que le C.

J'ai d'ailleurs un peu de mal avec les casts d'entiers vers flottants.
Autant un truc du genre :
void *foo; float *bar; bar = (float *) foo;
ne me gêne pas car on ne change pas le contenu de foo, autant un cast d'entier en flottant peut changer la valeur de foo.
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

14

Oh il y a encore plus simple : tu peux caster un long vers un char, pour ne garder que les bits de poids faible.
Un cast ne préserve pas forcément les données à l'identique.
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

15

Comme Zerosquare l'a écrit, un cast *explicite* n'a pas forcément à préserver la totalité des données lors de l'opération de conversion, c'est pour ça qu'il est explicite.
Mais c'est vrai que pour les float on autorise la conversion implicite en langage C traditionnel (ainsi que la plupart de ses dérivés comme le C++, le Java, le C# et d'autres encore…)
Je pense que par souci de clarté dans le code, on préfère autoriser float f = 5; plutôt que devoir écrire float f = 5f ou pire encore float f = (float)5; à chaque fois smile
Après, c'est vrai que certaines valeurs ne peuvent pas être représentées exactement par un float, mais ce sont des valeurs supérieures à 2^24 si je ne dis pas de bêtises. D'ailleurs je ne sais pas si le compilateur te génère un avertissement lorsque tu tentes de convertir une de ces valeurs… (Je pense que non)
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

16

si, visual te genere des warnings pour les casts implicites dans les deux sens. enfin, quand t'es en mode de warning maximal au moins. (et GCC probablement aussi, quand t'active les bons flags). mais autant ca peut etre utile de l'avoir pour les conversions float->int, autant pour les int->float, c'est juste mega-casse couilles...

et c'est pas tout a fait ca pour les valeurs representables. c'est plutot les valeurs entieres dont la representation binaire a une distance entre le premier et le dernier bit a 1 superieure a 24 bits.

par exemple, ces nombres la en binaire:

1011110100011101000000000000000000000000
1011110100011101000111110000000000000000

(40 bits significatifs au total, distance=16 pour le premier, et =24 pour le second) sont representables en float sans perte de precision quelconque

par contre ceux la:
1011110100011101000111111000000000000000
1011110100011101000111110000000000100000

une fois convertis en float, seront tronques en

1011110100011101000111110000000000000000

simplement parcequ'il n'y a que 23 bits de mantisse dans un float 32 bits IEEE754 + un bit de poids fort implicite qui vaut toujours 1. (et que l'exposant sur 8 bits est un exposant sur la base 2, donc on peut shifter ces 23 bits de mantisse de +127 ou -127 bits autour de zero).
avatar
HURRRR !

17

bon, en fait, tant qu'a faire, ca sera ptet plus clair pourquoi ca a ce comportement avec un exemple plus detaille:

le nombre
1011110100011101000111110000000000100100 en binaire
==
812237389860

structure d'un float IEEE754:
- 1 bit de signe
- 8 bits d'exposant
- 23 bits de mantisse + 1 bit implicite
[s][eeeeeeee][mmmmmmmmmmmmmmmmmmmmmmm]

pour convertir en float ce nombre:
1011110100011101000111110000000000100100

deja t'enleve le bit implicite:
(1)011110100011101000111110000000000100100
tu prends directement les 23 bits de mantisse:
[s][eeeeeeee][01111010001110100011111]

les bits perdus sont : 0000000000100100

ensuite, pour l'exposant, il faut compter le nombre de bits entre la virgule flottante (qui se trouve entre le bit implicite et le bit le plus significatif de la mantisse):
1.011110100011101000111110000000000100100
ca fait 39 bits

l'exposant a un bias de 127 (un exposant de 0 vaut 127, un exposant de -127 vaut 0 (et accessoirement, le nombre flottant devient un 'denormal', un nombre denormalise, on perd le bit a '1' implicite... bref)
donc les 8 bits d'exposant valent 127 + 39 = 10100110

[s][10100110][01111010001110100011111]

et c'est un nombre positif, donc le bit de signe est a 0:

[0][10100110][01111010001110100011111]

ce qui fait au final que le float vaudra:
(1)01111010001110100011111 0000000000000000

==
812237389824


EDIT: btw, j'ai dit une connerie dans le post d'avant, quand je disais "+127 ou -127 bits autour de zero", en fait c'est +126 ou -127, l'exposant qui vaut 127 (donc avec tous ses bits a 1) est une valeur speciale pour representer les infinis et les NaN, suivant les patterns de bits dans la mantisse. (de tete, les infinis doivent avoir les bits de la mantisse a 0, et les NaN doivent avoir au moins un bit a 1, le pattern exact permettant apres de differencier les differents types de NaN.. bref)

</horssujet> grin
avatar
HURRRR !

18

Édit : cross sur les dénormalisés

Et si l'exposant est représenté avec un biais, c'est uniquement pour que le zéro flottant ait ses 32 bits à 0 ; si les 3 champs (signe, exposant, mantisse) sont dans cet ordre-là, c'est pour que la comparaison soit la même opération qu'on considère ces 32 bits comme des flottants ou comme des entiers ^^


Sinon, je trouve que quand les données sont changées, il est plus logique d'utiliser une fonction float() qu'un cast ; bref je préfère la syntaxe python (ou tout autre langage qui fasse ça) que celle du C.
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

19

Edit: cross-cross sur les denormals triso

perso j'ai plutot tendance a foir float(truc) comme l'appel d'un constructeur du type float qu'une fonction a proprement parler.
c'est comment en python ?
avatar
HURRRR !

20

Et si l'exposant est représenté avec un biais, c'est uniquement pour que le zéro flottant ait ses 32 bits à 0 ; si les 3 champs (signe, exposant, mantisse) sont dans cet ordre-là, c'est pour que la comparaison soit la même opération qu'on considère ces 32 bits comme des flottants ou comme des entiers ^^


oui
(enfin, sauf pour les comparaisons signe/non-signe grin)
avatar
HURRRR !

21

Comme en GLSL ^^ (et ça peut passer pour un constructeur, les flottants sont des objets même si j'ai tendance à l'oublier ^^)
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

22

ok smile
avatar
HURRRR !

23

iwannabear (./16) :
et c'est pas tout a fait ca pour les valeurs representables. c'est plutot les valeurs entieres dont la representation binaire a une distance entre le premier et le dernier bit a 1 superieure a 24 bits.
Il faut aussi considérer le fait que lorsque tu as un flottant qui représente un entier qui tient sur 24 bits, tu peux être sûr (en sachant que c'est un entier ^^) que ton flottant représente bien la même valeur.

Parce que si je te donne un flottant avec un exposant supérieure à 23 (+127) et que je te dis que c'est un entier qui est représenté, tu ne peux pas savoir s'il y a une erreur ou pas smile
avatar

24

RHJPP (./23) :
Il faut aussi considérer le fait que lorsque tu as un flottant qui représente un entier qui tient sur 24 bits, tu peux être sûr (en sachant que c'est un entier ^^) que ton flottant représente bien la même valeur.
bah, ouais, c'est bien ce que je dis smile c'est plus representable de facon exacte lorsque la distance entre le premier et le dernier bit a 1 dans l'entier est superieure a 24 smile
forcement si l'entier tient sur 24 bits, la distance entre le premier et le dernier bit a 1 sera forcement toujours <= 24, donc il est toujours representable de facon exacte sur un float 32 bits.
Parce que si je te donne un flottant avec une mantisse supérieure à 23 (+127) et que je te dis que c'est un entier qui est représenté, tu ne peux pas savoir s'il y a une erreur ou pas smile

hum, j'ai pas compris? confus forcement tu peux pas savoir si la mantisse a ete tronquee, mais quel rapport avec ce que t'as quote?
(et j'imagine que tu veux dire un exposant superieur a 23 (+127), pas une mantisse?)
avatar
HURRRR !

25

Flanker (./18) :
Et si l'exposant est représenté avec un biais, c'est uniquement pour que le zéro flottant ait ses 32 bits à 0 ; si les 3 champs (signe, exposant, mantisse) sont dans cet ordre-là, c'est pour que la comparaison soit la même opération qu'on considère ces 32 bits comme des flottants ou comme des entiers ^^
Tiens, je ne savais pas ça, c'est pas bête hehe

avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

26

iwannabear (./24) :
Parce que si je te donne un flottant avec une mantisse supérieure à 23 (+127) et que je te dis que c'est un entier qui est représenté, tu ne peux pas savoir s'il y a une erreur ou pas smile.gif

hum, j'ai pas compris? confus forcement tu peux pas savoir si la mantisse a ete tronquee, mais quel rapport avec ce que t'as quote? (et j'imagine que tu veux dire un exposant superieur a 23 (+127), pas une mantisse?)
Oui exposant.

Le rapport ? bah, c'est juste une précision supplémentaire. Il y a une perte d'information lorsque l'exposant est plus grand que 23 (+127), on ne sait pas si on représente bien l'entier ou pas.
avatar

27

ah, vi ok smile
mais bon ca revient au meme que de dire ce que disait GoldenCrystal lorsque "l'entier fait plus de 24 bits" oui
parceque meme avec un exposant superieur a 23 t'as encore plein d'entiers representables...
mais oui si tu prends le probleme dans l'autre sens, a savoir a partir d'un float cree depuis un entier, etre sur que t'as pas eu de perte d'information, effectivement c'est tout ce que tu peux en deduire...
avatar
HURRRR !

28

iwannabear (./12) :
Oui, tu peux adopter cette syntaxe en C++, mais on me l'avait déconseillé dans le topic où j'avais posé la question, je sais plus pourquoi.


hum
etrange, je vois pas pourquoi non plus. a la limite ca peut se comprendre si tu considere le cast de types qui sont des pointeurs ou des references, vu que float*(truc) ou float&(truc) n'est pas une syntaxe valide, alors que les parentheses pour les casts C-style fonctionnent universellement pour tous les types, mais de toutes facons pour les types pointeurs/refs, c'est pas plus mal de passer par les casts type-safe du C++

Peut être parce qu'elle est moins orthogonale: on ne peut caster que des types primitifs ou en un mot, par exemple impossible de faire unsigned long(truc), logique mais bon ça fait que tu es obligé de te retrouver avec 2 syntaxes, et c'est encore plus confus qu'en utiliser une seule pas terrible...
Perso je ne fais plus beaucoup de C++ donc je ne peux pas bénéficier de ça, mais généralement j'ai mes propres types, nommés u8, s8, u16, etc. ou alors j'utilise uint8_t, etc. de <stdint.h>, ce qui m'évite d'avoir plusieurs mots. Pour les non signés j'utilise les int implicites, par exemple unsigned i = 0;
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

29

ouai pareil.. mais effectivement sans typedefs t'es vite baysay...
avatar
HURRRR !

30

#weekendlag# d'accord avec Flanker sur la conversion implicite en flottant par le cast, c'est un peu beaucoup haut-niveau pour du C.