Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

.NET 5 ajoutera la prise en charge des nombres à virgule flottante 16 bits
Avec le type Half

Le , par Stéphane le calme

46PARTAGES

6  0 
La spécification IEEE 754 définit de nombreux types à virgule flottante, notamment: binary16, binary32, binary64 et binary128. La plupart des développeurs sont des habitués de binary32 (équivalent à float en C#) et binary64 (équivalent à double en C#). Ils fournissent un format standard pour représenter une large gamme de valeurs avec une précision acceptable pour de nombreuses applications. .NET a toujours eu float et double et avec .NET 5 Preview 7, Microsoft a ajouté un nouveau type Half (équivalent à binary16)!

Half est un nombre binaire à virgule flottante qui occupe donc 16 bits (deux octets). Avec la moitié du nombre de bits en virgule flottante, Half peut représenter des valeurs dans la plage ±65504. Plus formellement, le type Half est défini comme un format d'échange 16 bits de base 2 destiné à prendre en charge l'échange de données en virgule flottante entre les implémentations. L'un des principaux cas d'utilisation du type Half est d'économiser de l'espace de stockage où le résultat calculé n'a pas besoin d'être stocké avec une précision totale. De nombreuses charges de travail de calcul profitent déjà du type Half : le machine learning, les cartes graphiques, les derniers processeurs, les bibliothèques SIMD natives, etc.

Les 16 bits du type Half sont divisés en:
  • Bit de signe (bit dans une représentation de nombres signés qui indique le signe d’un nombre): 1 bit.
  • Bits d'exposants: 5 bits.
  • Bits significatifs: 10 bits (avec 1 bit implicite non stocké).

Malgré le fait que les bits significatifs comportent 10 bits, Prashanth Govindarajan de l'équipe .NET explique que la précision totale est en réalité de 11 bits. Le format est supposé avoir un bit de tête implicite de valeur 1 (sauf si le champ d'exposant est composé entièrement de zéros, auquel cas le bit de tête a la valeur 0). Pour représenter le nombre 1 au format Half, nous utiliserons les bits:

Citation Envoyé par Half
0 01111 0000000000 = 1
Le bit de tête (notre bit de signe) est 0, indiquant un nombre positif. Les bits d'exposant sont 01111, ou 15 en décimal. Cependant, les bits d'exposant ne représentent pas directement l'exposant. Au lieu de cela, un biais d'exposant est défini qui permet au format de représenter à la fois des exposants positifs et négatifs. Pour le type Half, ce biais d'exposant est 15. Le vrai exposant est dérivé en soustrayant 15 de l'exposant stocké. Par conséquent, 01111 représente l'exposant e = 01111 (en binaire) - 15 (le biais de l'exposant) = 0. Le bit significatif est 0000000000, qui peut être interprété comme le nombre .bit_significatif(en base 2) en base 2, soit 0 dans notre cas . Si, par exemple, le bit significatif était 0000011010 (26 en décimal), on peut diviser sa valeur décimale 26 par le nombre de valeurs représentables en 10 bits (1 << 10): donc le bit significatif 0000011010 (en binaire) est 26 / ( 1 << 10) = 26/1024 = 0,025390625 en décimal. Enfin, comme nos bits d'exposant stockés (01111) ne sont pas tous à 0, nous avons un bit de tête implicite de 1. Par conséquent :

Citation Envoyé par Half
0 01111 0000000000 = 2^0 * (1 + 2^0) = 1

En général, les 16 bits d'une valeur Half sont interprétés comme -1 ^ (bit de signe) * 2 ^ (exposant stocké - 15) * (bit implicit + (bit significatif / 1024)). Un cas particulier existe pour l'exposant stocké 00000. Dans ce cas, les bits sont interprétés comme -1 ^ (bit de signe) * 2 ^ (- 14) * (0 + (bit significatif / 1024)). Examinons les représentations binaires de certains autres nombres au format Half:

Plus petite valeur positive non nulle

Citation Envoyé par Half
0 00000 0000000001 = -1^(0) * 2^(-14) * (0 + 1/1024) ≈ 0.000000059604645
(Notez que le bit implicite est 0 ici, car les bits des exposants stockés sont tous 0)

Le plus grand nombre normal

Citation Envoyé par Half
0 11110 1111111111 = -1^(0) * 2^(15) * (1 + 1023/1024) ≈ 65504
Infini négatif

Citation Envoyé par Half
1 11111 0000000000 = -Infinité
Une particularité du format est qu'il définit à la fois 0 positif et négatif:

Citation Envoyé par Half
1 00000 0000000000 = -0
Citation Envoyé par Half
0 00000 0000000000 = +0
Conversions vers / de float / double

Un Half peut être converti en / à partir d'un float / double en le lançant simplement:

Code : Sélectionner tout
float f = (float)half; Half h = (Half)floatValue;
Toute valeur Half, étant donné que Half utilise seulement 16 bits, peut être représentée sous la forme d'un float/double sans perte de précision. Cependant, l'inverse n'est pas vrai. Une certaine précision peut être perdue lors du passage de float/double à Half. Dans .NET 5.0, le type Half est principalement un type d'échange sans opérateur arithmétique défini dessus. Il ne prend en charge que les opérateurs d'analyse, de formatage et de comparaison. Toutes les opérations arithmétiques nécessiteront une conversion explicite en float/double. Les versions futures envisageront d'ajouter des opérateurs arithmétiques directement sur Half.

L'un des points que Microsoft considère est la possibilité ou non d'ajouter la prise en charge de Half sur un langage comme C# à l'avenir. La prise en charge au niveau du langage permettrait un identifiant tel que f16 (similaire au f qui existe aujourd'hui) et des conversions implicites / explicites. Ainsi, le type Half défini par la bibliothèque doit être défini d'une manière qui n'entraîne aucun changement de rupture si Half venait à être implémenté. Plus précisément, l'éditeur estime devoir faire attention lors de l'ajout des opérateurs au type Half. Les conversions implicites en float / double pourraient conduire à des changements de rupture potentiels si la prise en charge du langage était ajoutée.

Source : Microsoft

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de Captain Spic
Membre à l'essai https://www.developpez.com
Le 02/09/2020 à 13:37
Citation Envoyé par CaptainDangeax
Je ne vois pas trop l'intérêt de la chose. dotNet ne tourne qu'en environnement windows, donc sur nos PC windows. Et nos PC sont 32/64 bits, c'est à dire qu'un registre du processeur sera toujours en 32 bits. Un LD ou un MOV en assembleur se fera sur un registre en 32 bits. Sur un microcontrolleur où la place est limitée, je vois bien l'intéret de la chose, pour avoir un peu plus de précision avec 16 bits... Mais sur un PC / Windows, non vraiment je ne vois pas.
Même si le programme tourne en 32 ou 64 bits, et utilisera ces 32 ou 64 bits par cycle, en RAM, les valeurs sont stockées par lots de 8 bits (un octet).
On divise par deux l'espace nécessaire.
Pour un programme classique, je ne suis pas sûr que l'impact soit significatif.
Mais pour un programme qui manipule beaucoup de données de ce genre (Big Data, BDD, etc) ça peut faire beaucoup d'économie :
  • Pour un million d'entrée, on gagne 16 Mo
  • Pour un milliard, on gagne 16 Go !


Voilà pourquoi c'est intéressant

P.S. Sinon .NET est cross-plateforme depuis maintenant un certain temps (d'abord Roslyn, Xamarin, puis .Net Core et enfin .NET 5 qui va fusionner .Net Core et .Net Framework)
4  0 
Avatar de redcurve
Membre éclairé https://www.developpez.com
Le 02/09/2020 à 12:11
Citation Envoyé par CaptainDangeax Voir le message
Je ne vois pas trop l'intérêt de la chose. dotNet ne tourne qu'en environnement windows, donc sur nos PC windows. Et nos PC sont 32/64 bits, c'est à dire qu'un registre du processeur sera toujours en 32 bits. Un LD ou un MOV en assembleur se fera sur un registre en 32 bits. Sur un microcontrolleur où la place est limitée, je vois bien l'intéret de la chose, pour avoir un peu plus de précision avec 16 bits... Mais sur un PC / Windows, non vraiment je ne vois pas.
Toi t'as rien capté depuis 10 ans
5  3 
Avatar de redcurve
Membre éclairé https://www.developpez.com
Le 02/09/2020 à 16:28
Citation Envoyé par CaptainDangeax Voir le message
Prends un programme compilé et regarde les instructions MOV ou LD : elles sont toutes en 32 bits. Alors si c'est pour charger 2 fois 16 bits puis faire un SWAP pour accéder à l'autre mot, non je ne vois pas l'intérêt. Mais bon je parle à des développeurs dotNet, pas à des développeurs C ou ASM.
Toujours à coté de la plaque

Top pour nos programmes de machine learning
2  0 
Avatar de LinxBe
Membre à l'essai https://www.developpez.com
Le 05/09/2020 à 1:01
Citation Envoyé par CaptainDangeax Voir le message
C'est bien ce petit ton moqueur depuis le début. Et sinon, c'est quand la dernière fois que tu as pondu un programme en ASM ?
Pourquoi parlez-vous de ASM ?
Il ne s'agit pas d'un problème de programmation, mais de STOCKAGE !
1  0 
Avatar de Kropernic
Expert confirmé https://www.developpez.com
Le 22/09/2020 à 9:18
C'est bien beau de fusionner tout ça mais quid des types spatiaux ?

Aux dernières nouvelles, ils ne sont toujours pas supporté par .Net Core. Enfin il y a bien un moyen détourner en utilisant Net Topology Suite mais pour avoir tester cette librairie, je ne suis pas convaincu du tout...

Est-ce que cette fusion .Net Fx et .Net Core fera qu'on pourra utiliser la librairie Microsoft.SqlServer.Types (SqlServerSpatial140.dll) ?
0  0 
Avatar de CaptainDangeax
Membre éprouvé https://www.developpez.com
Le 02/09/2020 à 14:01
Jamais vu de dotNet sur un µcontrolleur. C'est C + ASM.

Prends un programme compilé et regarde les instructions MOV ou LD : elles sont toutes en 32 bits. Alors si c'est pour charger 2 fois 16 bits puis faire un SWAP pour accéder à l'autre mot, non je ne vois pas l'intérêt. Mais bon je parle à des développeurs dotNet, pas à des développeurs C ou ASM.
0  4 
Avatar de CaptainDangeax
Membre éprouvé https://www.developpez.com
Le 04/09/2020 à 14:12
Citation Envoyé par redcurve Voir le message
Toujours à coté de la plaque

Top pour nos programmes de machine learning
C'est bien ce petit ton moqueur depuis le début. Et sinon, c'est quand la dernière fois que tu as pondu un programme en ASM ?
1  5 
Avatar de CaptainDangeax
Membre éprouvé https://www.developpez.com
Le 02/09/2020 à 11:55
Je ne vois pas trop l'intérêt de la chose. dotNet ne tourne qu'en environnement windows, donc sur nos PC windows. Et nos PC sont 32/64 bits, c'est à dire qu'un registre du processeur sera toujours en 32 bits. Un LD ou un MOV en assembleur se fera sur un registre en 32 bits. Sur un microcontrolleur où la place est limitée, je vois bien l'intéret de la chose, pour avoir un peu plus de précision avec 16 bits... Mais sur un PC / Windows, non vraiment je ne vois pas.
1  7