Comment faire la sérialisation des nombres flottants sur le réseau?

J’ai trouvé un morceau de code pour faire la sérialisation des nombres flottants sur le réseau.

uint32_t htonf(float f) { uint32_t p; uint32_t sign; if (f < 0) { sign = 1; f = -f; } else { sign = 0; } p = ((((uint32_t)f)&0x7fff)<<16) | (sign<<31); // whole part and sign p |= (uint32_t)(((f - (int)f) * 65536.0f))&0xffff; // fraction return p; } 

Spec: Le code ci-dessus est une sorte d’implémentation naïve qui stocke un float dans un nombre 32 bits. Le bit haut (31) est utilisé pour stocker le signe du nombre (“1” signifie négatif) et les sept bits suivants (30-16) sont utilisés pour stocker la partie entière du nombre flottant. Enfin, les bits restants (15-0) sont utilisés pour stocker la partie fractionnaire du nombre.

Les autres vont bien mais je ne peux pas comprendre ce que cela signifie. Comment cela nous obtient-il les 15-0 bits? Pourquoi avons-nous besoin du “* 65536.0f”?

 p |= (uint32_t)(((f - (int)f) * 65536.0f))&0xffff 

Tout le monde peut expliquer à ce sujet?

 f - (int)f 

vous donne la fraction du nombre. Vous voulez stocker cette fraction en 16 bits, alors considérez-la comme une fraction avec 2 ^ 16 comme dénominateur. Le numérateur est:

 (f - (int)f) * 65536.0f) 

Le rest utilise simplement le décalage de bits pour le compresser dans les bons bits du nombre de 32 bits. Ensuite, cet int de 32 bits est sérialisé sur le réseau comme n’importe quel autre int de 32 bits, et probablement l’inverse de la routine ci-dessus est utilisé pour recréer un nombre à virgule flottante.

Vous pourriez utiliser un syndicat.

 uint32_t htonf(float f) { union { float f1; uint32_t i1; }; f1 = f; return i1; }