J'essaie d'écrire une routine de byteswap pour un programme C ++ en cours d'exécution sur Win XP. Je compile avec Visual Studio 2008. C'est ce que j'ai proposé: et une fonction à tester: p> Obtenir ces chiffres ne correspondant pas: P>
-76.789999999988126 -76.790000000017230 0.000000000029104
-30.499999999987718 -30.499999999994994 0.000000000007276
41.790000000014508 41.790000000029060 -0.000000000014552
90.330000000023560 90.330000000052664 -0.000000000029104
5 Réponses :
Bien qu'un Peut-être que vous puissiez forcer les variables à vivre dans la mémoire principale en prenant leur adresse (et en l'imprimant, pour empêcher le compilateur de l'optimiser), mais je ne suis pas certain que cela est garanti de travailler. P> double code> dans la mémoire principale est de 64 bits, sur X86 Les registres de double précision CPus sont de 80 bits de large. Donc, si l'une de vos valeurs est stockée dans un registre dans l'ensemble, mais l'autre fait un aller-retour à la mémoire principale et est tronqué à 64 bits, cela pourrait expliquer les petites différences que vous voyez. P>
+1: Je pense que c'est ce qui se passe ici: "A" est détenir dans un registre et est incrémenté là-bas alors que "C" est en mémoire.
b = byteswap(a); That's a problem. After swapping the bytes, the value is no longer a proper double. Storing it back to a double is going to cause subtle problems when the FPU normalizes the value. You have to store it back into an __int64 (long long). Modify the return type of the method.
Cela a du sens! D'accord, je vais regarder dans ça et vous revenir à vous
@Hans, je pense que vous êtes sur quelque chose ici. J'en ai fait mention dans ma réponse ici: Stackoverflow.com/a/64056527/4561887 . Je ne comprends pas complètement moi-même.
D'accord, ça marche! Hans Passant avait raison. Ils m'ont fait penser avec le commentaire "non plus double". Donc, vous ne pouvez donc pas bytewap un flotteur dans un autre float car il peut s'agir d'un format inapproprié, vous devez donc byteswap à un tableau de charcuterie et de retourner. Ceci est le code que j'ai utilisé: p> et une fonction de test simple: p>
D'accord, découvrez qu'il y a une meilleure façon. L'autre façon, vous devez vous inquiéter de l'ordre que vous emballez / décompressez des choses. De cette façon, vous ne: p> envoyer: p> recv: p>
Débarrassez-vous de ceci: memcpy (in, v, 4); code> et simplement copier-swap directement dans
out code> à partir de
v code>, puis
memcpy code> Les valeurs échangées de
out code> dans
v code>. Cela vous permet d'économiser une copie inutile en réduisant vos copies de l'ensemble de la matrice de 3 à 2.
Il existe également une optimisation supplémentaire pour réduire les copies de l'ensemble de la matrice de 2 à 1,5: Copier la moitié gauche de la matrice en variables temporaires et la moitié droite du tableau droit dans la moitié gauche, échangeant de manière appropriée. Ensuite, copiez des variables temporaires, qui contiennent l'ancienne moitié gauche de la matrice, dans la moitié droite du tableau, échange de manière appropriée. Cela se traduit par l'équivalent de seulement 1.5 opérations de copie de l'ensemble de la matrice, pour être plus efficace. Faites tout cela sur place dans la matrice d'origine, mis à part les variables temporaires dont vous avez besoin pour la moitié de la matrice.
Voir ma réponse: Stackoverflow.com/a/64056527/4561887
(tel qu'un Voici un moyen d'améliorer l'efficacité de l'efficacité de 3 TOUTES COPY Opérations du tableau à 1.5 Opérations de copie enbles de la matrice. Voir aussi les commentaires que j'ai laissés sous votre réponse . P> utilisation : p> note, cependant, que @Hans Passant semble être sur quelque chose ici . Bien que ce qui précède fonctionne parfaitement sur tout type signé ou non signé entier em> et semble fonctionner sur sur de nombreux systèmes 64 bits, Gardez TH ci-dessus à l'esprit au cas où vous voyez des problèmes avec int16_t code>,
uint16_t code>,
uint32_t code>,
float code>,
double code>, etc.): p>
float code> et
double code> pour moi aussi, cela semble être cassé sur
double long code>. Je pense que c'est parce que quand je stocke le double code> double code> retour dans un
double code> variable code>, s'il est déterminé à être pas-a-valide
long double Code> Représentation plus, quelque chose change automatiquement quelques-uns des octets échangés ou quelque chose. Je ne suis pas tout à fait sûr. P>
Long Double code> est de 16 octets, donc peut-être que la solution consiste à conserver la version échangée du
long Double CODE> à l'intérieur d'un tableau de 16 octets et ne tentez pas de l'utiliser ou de le jeter à un
Double code> à partir du tableau
uint8_t code> 16 octet jusqu'à a) Il a été envoyé au récepteur (où l'endansion du système est opposée, de sorte qu'il est en forme maintenant) et / ou b) d'octet-levé à nouveau de sorte que c'est un double
valide double code> à nouveau. < / p>
float code> ou
double code> Types, comme je le vois avec seulement
Long Double Code > types. p> h2>
Pourriez-vous clarifier ce qui a été inventé exactement dans la Quake 2? Sûrement pas l'idée d'avoir un double et un INT64 en tant que champs de la même union?
Désolé .. j'ai appris C de côté de la Quake2, j'aime donc prétendre que c'est le plus grand: D Je le vois (union) partout maintenant.
Associé: Stackoverflow.com/Questions/32573923/bylte-swap -with-an-array