8
votes

convertir le tableau des octets en double - C

J'essaie d'obtenir la valeur numérique (double) à partir d'un tableau d'octets de 16 éléments, comme suit:

a = input[i] * pow(2,8*i);


4 commentaires

Vous n'avez pas dit ce que "contributions [16]" essaie de représenter. Est-ce une valeur intégrale de 128 bits, ou autre chose?


Vous stockez le numéro dans "Entrée" sous la forme d'un entier non signé de 128 bits?


@RODDY: Depuis son algorithme, il semble que les personnages soient les coefficients dans un polynôme de 15 ème ordre (avec la base 256). (@paolo_, est-ce correct?)


Comme dit par Adrian P., le vecteur d'entrée [16] est une séquence de bits que je veux représenter comme un entier non signé de 128 bits


7 Réponses :


0
votes

Bien basé sur la priorité de l'opérateur Le côté droit de la droite de xxx

est évalué avant qu'il ne soit converti en un double, de sorte que vous changez d'entrée [i] par 8 * i bits, qui stocke son résultat dans une variable temporaire 32 bits et déborde donc. Vous pouvez essayer ce qui suit: xxx

EDIT: Je ne sais pas quelle taille d'un double est sur votre système, mais sur le mien, c'est 8 octets , Si tel est le cas pour vous, la seconde moitié de votre matrice d'entrée ne sera jamais vue car le décalage débordera même le double type.


0 commentaires

1
votes

2 commentaires

Je crois que l'entrée n'est pas ASCII, mais en fait une valeur de point flottante dans un tampon.


Seulement pertinent si l'entrée est un format de chaîne d'un numéro, s'il a largué un double à mémoire, puis le chargé comme un tableau de charcuterie, cela échouerait.



1
votes

essayez-vous de convertir une représentation de chaîne d'un nombre à un nombre réel? Dans ce cas, le c-standard ATOF est votre meilleur ami.


0 commentaires

4
votes

EDIT: cela ne fonctionnera pas (voir commentaire) sans quelque chose comme __ int128 . xxx

L'expression entrée [i] est promu int ( 6.3.1.1 ), qui est 32 bits sur votre machine. Pour surmonter ce problème, l'opérande de Leuthand doit être 64 bits, comme dans xxx

ou xxx

et rappelez-vous de l'endansion


1 commentaires

Cela ne va-t-il pas trop déborder une fois qu'il essaie de faire le (<< 8 * I) pour la partie I> = 9 partie de la boucle car cette boucle semble tenter de convertir une valeur de 128 bits en un double, ou je manque quelque chose ici?



2
votes

En bref, non, vous ne pouvez pas convertir une séquence de octet S directement dans un double par bit-shifting comme indiqué par votre échantillon de code.

octet , un type d'entier et double , un type de point flottant (c'est-à-dire pas un type d'entier) ne sont pas compatibles dans le sens (c'est-à-dire que vous ne pouvez pas simplement bander à des valeurs d'un groupe d'octets dans un type de point flottant et s'attendre à un résultat équivalent.)

1) En supposant que le tableau d'octet est un tampon de mémoire référençant une valeur entière, vous devriez être en mesure de convertir votre octet Array dans un entier de 128 bits via un décalage de bits puis convertir ce entier résultant dans un double . N'oubliez pas que les problèmes d'endian peuvent entrer en jeu en fonction de l'architecture du processeur.

2) En supposant que le tableau d'octet est un tampon de mémoire contenant une double valeur de 128 bits longue et en supposant qu'il n'y ait pas de Endian Problèmes, vous devriez être capable de mémoriser la valeur de la matrice d'octet dans la double valeur de double valeur xxx


0 commentaires

4
votes

Le problème ici est que les variables 32 bits ne peuvent pas être déplacées plus de 4 * 8 fois, c'est-à-dire que votre code fonctionne uniquement pour 4 caractères.

Ce que vous pourriez faire est de trouver le premier caractère important et utilisez la loi de Horner : A n sub> x n sup> + a n-1 sub> n-1 sup> ... = ((.. . (A N SUB> X + A N-1 SUB>) .x + A N-2 SUB>). x + ...) + a 0 SUB> Comme suit: P>

char coefficients[16] = { 0, 0, ..., 14, 15 };
int exponent=15;
double result = 0.;

for(int exponent = 15; exp >= 0; --exp ) {
   result *= 256.; // instead of <<8.
   result += coefficients[ exponent ];
}


0 commentaires

2
votes

Pourquoi ne pas simplement lancer le tableau sur un double pointeur?

unsigned char input[16];

double* pd = (double*)input;

for (int i=0; i<sizeof(input)/sizeof(double); ++i)
    cout << pd[i];


1 commentaires

De loin et loin la solution la plus simple!