C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

float => unsigned int et extraction bits poids fort

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
Michael
Guest





PostPosted: Wed Mar 22, 2006 11:06 pm    Post subject: float => unsigned int et extraction bits poids fort Reply with quote



Bonsoir à tous,

voilà ce que je n'arrive pas à faire:

je dois extraire un flottant codé sur 4 octets depuis un fichier binaire,
que je dois convertir en entier non signé.

Ensuite je dois extraire les bits de poids fort et faible et récupérer
ces deux valeurs...

Récupérer le flottant, j'y arrive:

float IntelDataHandler::readFloat(std::ifstream & source ) const
{
uchar tmp[ 4 ] ;
if (!source.read(reinterpret_cast<char*>(tmp),4))
throw Exception("Impossible de lire le fichier");

float * f = (float *)tmp;
float flt = *f;

return flt;
}

Mais pour le reste? Est-ce que la conversion et l'extraction des bits est
différente selon qu'on soit sur des représentations intel, MIPS ou DEC?

Et comment je peux extraire les deux données?

Est-ce que je ne peux tout simplement pas, au lieu de lire un float, lire
deux short, me donnant directement les bonnes valeurs?

short IntelDataHandler::readShort(std::ifstream & source ) const
{
uchar tmp[ 2 ] ;
if (!source.read(reinterpret_cast<char*>(tmp),2))
throw Exception("Impossible de lire le fichier");

return (tmp[ 1 ] << Cool | tmp[ 0 ] ;
}

Merci d'avance

Mike
Back to top
Fabien LE LEZ
Guest





PostPosted: Thu Mar 23, 2006 12:06 am    Post subject: Re: float => unsigned int et extraction bits poids fort Reply with quote



J'ai osé écrire :

Quote:
static size_t const TAILLE_BUF= sizeof (float);
char buf[TAILLE_BUF];
source.read (buf, TAILLE_BUF); // + contrôle d'erreur
float reponse= *reinterpret_cast<float const*> (buf);

Bien sûr, ce code ne peut fonctionner que si le fichier binaire a été
créé avec un code analogue, compilé avec le même compilo (ou un
compilo compatible).

Enfin bon, tout ça est bien casse-gueule. Bon débogage...
Back to top
Fabien LE LEZ
Guest





PostPosted: Thu Mar 23, 2006 12:06 am    Post subject: Re: float => unsigned int et extraction bits poids fort Reply with quote



On 22 Mar 2006 22:32:43 GMT, Michael
<michael_delva.enlever (AT) hotmail (DOT) com>:

Quote:
uchar tmp[ 4 ] ;

Pourquoi uchar ?

Quote:
if (!source.read(reinterpret_cast<char*>(tmp),4))
throw Exception("Impossible de lire le fichier");

float * f = (float *)tmp;

Et pourquoi un cast à la C ici ?


Si tu veux lire un nombre dans un fichier de façon aussi brute que ça,
void* pourrait être pas mal. Ou bien char*, puisque c'est le type
attendu par istream::read.

static size_t const TAILLE_BUF= sizeof (float);
char buf[TAILLE_BUF];
source.read (buf, TAILLE_BUF); // + contrôle d'erreur

float reponse= *reinterpret_cast<float const*> (buf);
return reponse;


Quote:
Est-ce que la conversion et l'extraction des bits est
différente selon qu'on soit sur des représentations intel, MIPS ou DEC?

C'est surtout la représentation d'un float en mémoire qui risque
d'être différente...

De toutes façons, si tu lis des nombres depuis un fichier de cette
façon, c'est fortement dépendant de la plate-forme.



Quote:
Ensuite je dois extraire les bits de poids fort et faible et récupérer
ces deux valeurs...

Ça, c'est très simple.

unsigned int i; // Ou unsigned short, unsigned long, etc.

Le bit de poids faible est : i&1

Le bit de poids fort, c'est à peine plus compliqué :
i >> (sizeof(i)*CHAR_BIT-1)
Back to top
Sylvain
Guest





PostPosted: Thu Mar 23, 2006 12:06 am    Post subject: Re: float => unsigned int et extraction bits poids fort Reply with quote

Fabien LE LEZ wrote on 23/03/2006 00:33:
Quote:
J'ai osé écrire :

static size_t const TAILLE_BUF= sizeof (float);
char buf[TAILLE_BUF];
source.read (buf, TAILLE_BUF); // + contrôle d'erreur
float reponse= *reinterpret_cast<float const*> (buf);

Bien sûr, ce code ne peut fonctionner que si le fichier binaire a été
créé avec un code analogue, compilé avec le même compilo (ou un
compilo compatible).

pourquoi donc ?

Sylvain.
Back to top
Marc Boyer
Guest





PostPosted: Thu Mar 23, 2006 7:52 am    Post subject: Re: float => unsigned int et extraction bits poids fort Reply with quote

Le 22-03-2006, Fabien LE LEZ <gramster (AT) gramster (DOT) com> a écrit :
Quote:
On 22 Mar 2006 22:32:43 GMT, Michael
michael_delva.enlever (AT) hotmail (DOT) com>:

uchar tmp[ 4 ] ;

Pourquoi uchar ?

if (!source.read(reinterpret_cast<char*>(tmp),4))
throw Exception("Impossible de lire le fichier");

float * f = (float *)tmp;

Et pourquoi un cast à la C ici ?


Si tu veux lire un nombre dans un fichier de façon aussi brute que ça,
void* pourrait être pas mal. Ou bien char*, puisque c'est le type
attendu par istream::read.

static size_t const TAILLE_BUF= sizeof (float);
char buf[TAILLE_BUF];
source.read (buf, TAILLE_BUF); // + contrôle d'erreur

float reponse= *reinterpret_cast<float const*> (buf);

Et si les contraintes d'alignement de float* ne sont
pas respectées par &buf, que ce passe-t-il ?
Pourquoi pas un tout bête
memcpy(&reponse, buf, sizefof(reponse) );

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. Paul Éluard)
Back to top
kanze
Guest





PostPosted: Thu Mar 23, 2006 10:06 am    Post subject: Re: float => unsigned int et extraction bits poids fort Reply with quote

Fabien LE LEZ wrote:
Quote:
On 22 Mar 2006 22:32:43 GMT, Michael
michael_delva.enlever (AT) hotmail (DOT) com>:

uchar tmp[ 4 ] ;

Pourquoi uchar ?

Parce qu'il va les traiter au niveau des bits par la suite ?
Avec peut-être des décalages ?

Dans beaucoup de milieu, uchar est le type conventionnel pour
la mémoire brute. Des bits en quelque sorte.

Quote:
if (!source.read(reinterpret_cast<char*>(tmp),4))
throw Exception("Impossible de lire le fichier");

float * f = (float *)tmp;

Et pourquoi un cast à la C ici ?

Pour masquer un reinterpret_cast, qui risque de provoquer un
core dump sur certaines machines (dont la mienne). Note bien
que rien ne garantit que tmp soit correctement aligné ; ici,
c'est probable parce que c'est la seule variable locale, mais en
ajoute une autre, et qui sait. Et même si c'est aligné, rien ne
garantit que les valeurs dans ces quatres octets ne
correspondent pas à une valeur interdite sur mon architecture.

Maintenant, si il se trouve sur une machine Intel 80x86, où des
erreurs d'alignement ne sont pas fatales (elles rallentissent
l'exécution seulement), et que les données qu'il lit ont été
écrit par un programme qui tournait lui aussi sur une machine
Intel 80x86, et que les deux ont été compilé avec un compilateur
rélativement récent, le code marchera comme prévu. Mais ça fait
beaucoup de « si », à mon avis.

Quote:
Si tu veux lire un nombre dans un fichier de façon aussi brute
que ça, void* pourrait être pas mal.

Sauf qu'on ne peut pas définir des tableaux de void. Ce qui
manque un peu à C++, peut-être, c'est un type « byte » -- comme
j'ai dit, dans beaucoup de milieu, uchar y sert par convention.

Quote:
Ou bien char*, puisque
c'est le type attendu par istream::read.

C'est parce que la distinction entre lire des caractères et lire
des multiplets binaires n'est pas bien nette dans la
bibliothèque standard. Donc, par exemple, son code suppose que
si le istream est réelement un ifstream (probablement le cas),
il a été ouvert avec mode binary, et qu'il a imbué le locale
"C".

Quote:
static size_t const TAILLE_BUF= sizeof (float);
char buf[TAILLE_BUF];
source.read (buf, TAILLE_BUF); // + contrôle d'erreur

Ce qui ne résoud en rien le problème d'alignement. Et qui
suppose aussi que les flottants dans le fichier ont la même
taille et la même représentation que les flottants internes, ce
qui est loin d'être donné. (Plus tard, il a fait mention des
formats Intel, MIPS et DEC. Ce qui suggère fort que dans au
moins deux cas sur trois, le format des flottants dans le
fichier n'est pas identique au format interne -- si le code
tourne sur un IBM 390, dans aucun cas.)

Quote:
float reponse= *reinterpret_cast<float const*> (buf);

Encore : en cas de problème d'alignement, sur ma machine, au
moins, ça fait boom. Même si on est 100% sûr que les formats
soient identiques, il faut se servir de memcpy. Le seul cas où
de tels conversions marchent, c'est si 1) le buffer a été alloué
dynamiquement, afin de garantir l'alignement, 2) tu lis le
fichier par blocs assez grand pour respecter tout alignement
dans le fichier même, et 3) le protocol a été conçu exprès de
façon à ce que toutes les données soient suffisamment alignées
pour ton processeur.

Note que ce dernier point est rarement rempli -- la plupart des
protocols (ou au moins XDR) ont été conçu à un époque où un
alignement de quatre suffisait pour tout les machines, alors
qu'aujourd'hui, il en faut souvent huit pour un double ou un
long.

Quote:
return reponse;

Est-ce que la conversion et l'extraction des bits est
différente selon qu'on soit sur des représentations intel,
MIPS ou DEC?

C'est surtout la représentation d'un float en mémoire qui
risque d'être différente...

Qui est différent ! DEC et Intel, je connais, bien que mes
souvenirs de DEC ne sont pas parfaits. (Je ne m'en suis plus
servi depuis au moins 1979.) Je crois, mais je suis loin d'en
être sûr, que le format MIPS est le même que celui du Sparc ; si
c'est le cas, je le connais très bien. Et il n'est pas pareil
aux autres.

Mais il me semble qu'on avait traité ce thème dans un fil il y a
peu de temps.

Quote:
De toutes façons, si tu lis des nombres depuis un fichier de
cette façon, c'est fortement dépendant de la plate-forme.

Oui et non. Lire des nombres de cette façon suppose qu'ils ont
été écris de cette façon depuis la même plate-forme. Je le fais,
par exemple, dans des fichiers temporaires, que je rélis plus
tard dans la même programme ; je le fais aussi quand je passe
des données par une pipe à un autre programme sur la même
machine, développé en commun avec le premier (c-à-d donc compilé
et linké avec le même compilateur et les mêmes options). Dans
les deux cas, le code ne dépend pas de la plate-forme, et marche
aussi bien sous Linux sur PC que sous Solaris sur Sparc.

En revanche, sans changer de plate-forme... Sous MS-DOS et des
compilateurs Microsoft, ça ne marche pas forcément si le code
qui écrit et le code qui lit ont été compilé avec des versions
différentes du compilateur.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Back to top
kanze
Guest





PostPosted: Thu Mar 23, 2006 10:06 am    Post subject: Re: float => unsigned int et extraction bits poids fort Reply with quote

Michael wrote:

Quote:
voilà ce que je n'arrive pas à faire:

je dois extraire un flottant codé sur 4 octets depuis un
fichier binaire,

En quel format ? XDR ?

Quote:
que je dois convertir en entier non signé.

Avec quelles règles d'arrondi ? Où est-ce qu'on sait qu'a
priori, le flottant représente un entier dans l'intervale
représentable dans le type cible (int, long ?) ?

Quote:
Ensuite je dois extraire les bits de poids fort et faible et
récupérer ces deux valeurs...

Je ne suis pas sur ce que tu veux dire par là. A priori, si tu
as un int32_t, « ((uint32_t)(-1) << (32 - n)) & valeur »
récupère les n bits de poids forts. Alternativement, on pourrait
vouloir les avoir comme valeur, avec simplement « valeur >> (32
- n) » (mais attention au comportement en cas de valeur
négative).

Quote:
Récupérer le flottant, j'y arrive:

float IntelDataHandler::readFloat(std::ifstream & source ) const
{
uchar tmp[ 4 ] ;
if (!source.read(reinterpret_cast<char*>(tmp),4))
throw Exception("Impossible de lire le fichier");

float * f = (float *)tmp;
float flt = *f;

return flt;
}

Ça ne marche que si le flottant a été écrit par un programme
compilé avec la même version du même compilateur, compilé avec
les mêmes options, pour la même architecture. Et encore... rien
ne garantit que tmp soit correctement aligné pour contenir un
float.

Quote:
Mais pour le reste? Est-ce que la conversion et l'extraction
des bits est différente selon qu'on soit sur des
représentations intel, MIPS ou DEC?

Certainement. Si tu ne connais pas la représentation des
flottants dans le fichier, tu es mal barré. Si tu le connais, il
faut lire les octets, en extraire la mantisse, l'exposant et la
signe, et les réassembler dans le format interne au coup de
ldexp et al.

J'ai du code qui le fait de façon portable pour XDR, c-à-d des
flottants IEEE sur quatre ou huit octets, avec la mantisse sur
les premiers octets, puis l'exposant, et la signe sur le bit du
poids fort du dernier octet. Ce qui correspond, je crois, au
format MIPS, et en inversant les octets, au format Intel. DEC
est légèrement différent : d'après mes souvenirs, les valeurs
sur quatre octets ne diffèrent d'Intel que par l'excès de
l'exposant, au moins pour les valeurs « normalisées » (et zéro).
Pour les flottants de huit octets, en revanche, c'est nettement
différent.

Quote:
Et comment je peux extraire les deux données?

Est-ce que je ne peux tout simplement pas, au lieu de lire un
float, lire deux short, me donnant directement les bonnes
valeurs?

Certainement pas.

Quote:
short IntelDataHandler::readShort(std::ifstream & source ) const
{
uchar tmp[ 2 ] ;
if (!source.read(reinterpret_cast<char*>(tmp),2))
throw Exception("Impossible de lire le fichier");

return (tmp[ 1 ] << Cool | tmp[ 0 ] ;
}

Ce qui suppose des shorts en format Intel, et non XDR.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Back to top
Michael
Guest





PostPosted: Thu Mar 23, 2006 11:06 am    Post subject: Re: float => unsigned int et extraction bits poids fort Reply with quote

Ce que je cherche à faire se trouve ici:

http://www.c3d.org/HTML/3ddatafloatingpointformat.htm

Je lis les words 7 et 8 avec un ReadFloat adapté au fichier (Intel ou DEC).
Je veux convertir le flottant récupéré en entier signé (j'avais mal lu, il
doit pas être unsigned), pour récupérer deux valeurs, situées sur le bit de
poids fort et le bit de poids faible.

La première valeur pouvant ensuite être découpée en 8 valeurs (d'ailleurs
comment faire?) et la seconde indiquant un degré de précision, que je
voudrais récupérer.

J'ai ça pour le moment, mais je ne suis pas sûr que ce soit bon:

coords.x = file->ReadFloat();
coords.y = file->ReadFloat();
coords.z = file->ReadFloat();

int i = file->ReadFloat();

int pFaible = i & 1;
int pFort = i >> (sizeof(i)*CHAR_BIT-1);
Back to top
Michael
Guest





PostPosted: Thu Mar 23, 2006 11:06 am    Post subject: Re: float => unsigned int et extraction bits poids fort Reply with quote

Quote:
je dois extraire un flottant codé sur 4 octets depuis un
fichier binaire,

En quel format ? XDR ?

Intel ou DEC. J'ai déjà les routines d'extraction de ce flottant, que tu
m'avais donné dans un fil précédent.

Quote:
que je dois convertir en entier non signé.

Avec quelles règles d'arrondi ? Où est-ce qu'on sait qu'a
priori, le flottant représente un entier dans l'intervale
représentable dans le type cible (int, long ?) ?

Le flottant représente un entier, positif de surcroit.

Quote:
Ensuite je dois extraire les bits de poids fort et faible et
récupérer ces deux valeurs...

Je ne suis pas sur ce que tu veux dire par là. A priori, si tu
as un int32_t, « ((uint32_t)(-1) << (32 - n)) & valeur »
récupère les n bits de poids forts. Alternativement, on pourrait
vouloir les avoir comme valeur, avec simplement « valeur >> (32
- n) » (mais attention au comportement en cas de valeur
négative).

Récupérer le flottant, j'y arrive:

float IntelDataHandler::readFloat(std::ifstream & source ) const
{
uchar tmp[ 4 ] ;
if (!source.read(reinterpret_cast<char*>(tmp),4))
throw Exception("Impossible de lire le fichier");

float * f = (float *)tmp;
float flt = *f;

return flt;
}

Ça ne marche que si le flottant a été écrit par un programme
compilé avec la même version du même compilateur, compilé avec
les mêmes options, pour la même architecture. Et encore... rien
ne garantit que tmp soit correctement aligné pour contenir un
float.

J'ai testé avec plusieurs fichiers écrits par des machines x86
différentes, et ça marche tout le temps. Dans le cas de fichiers DEC,
j'ai une autre routine adaptée, que tu m'avais donné aussi je crois bien
;)

float DECDataHandler::readFloat(std::ifstream & source ) const
{
uchar tmp[ 4 ] ;
if (!source.read(reinterpret_cast<char*>(tmp),4))
throw Exception("Impossible de lire le fichier");

long mantis = (tmp[2] & 0xff) + ((tmp[3] & 0xffl) << Cool + (((tmp[0] &
0x7fl) | 0x80) << 16);
short exp = (tmp[1] & 0x7f) * 2 + ((tmp[0] & 0x80) ? 1 : 0);
if (tmp[1] & 0x80)
mantis = -mantis;

float flt = (mantis || exp) ? ((float) ldexp (mantis, (exp - 128 - 24)))
: 0;

return flt;
}


Quote:
Et comment je peux extraire les deux données?

Est-ce que je ne peux tout simplement pas, au lieu de lire un
float, lire deux short, me donnant directement les bonnes
valeurs?

Certainement pas.

Est-ce que du coup, comme les float que je récupère via les routines que
j'ai données plus haut sont corrects, je peux utiliser le code suivant
donné par Fabien plus haut?

unsigned int i; // Ou unsigned short, unsigned long, etc.

Le bit de poids faible est : i&1

Le bit de poids fort, c'est à peine plus compliqué :
i >> (sizeof(i)*CHAR_BIT-1)



Quote:
short IntelDataHandler::readShort(std::ifstream & source ) const
{
uchar tmp[ 2 ] ;
if (!source.read(reinterpret_cast<char*>(tmp),2))
throw Exception("Impossible de lire le fichier");

return (tmp[ 1 ] << Cool | tmp[ 0 ] ;
}

Ce qui suppose des shorts en format Intel, et non XDR.

C'est le cas.
Back to top
Michael
Guest





PostPosted: Thu Mar 23, 2006 11:06 am    Post subject: Re: float => unsigned int et extraction bits poids fort Reply with quote

Quote:
Mais il me semble qu'on avait traité ce thème dans un fil il y a
peu de temps.

Oui, par moi, ici
Xns9772F3B9D81F4michaeldelvaenleverh (AT) 212 (DOT) 27.42.136
Back to top
Michael
Guest





PostPosted: Thu Mar 23, 2006 11:06 am    Post subject: Re: float => unsigned int et extraction bits poids fort Reply with quote

Pardon, ici:

http://groups.google.com/group/fr.comp.lang.c++/browse_frm/thread/12ff0eb1a
39611c9/0fcfc7756ac7b2de?q=C3D&rnum=1#0fcfc7756ac7b2de
Back to top
kanze
Guest





PostPosted: Thu Mar 23, 2006 2:06 pm    Post subject: Re: float => unsigned int et extraction bits poids fort Reply with quote

Michael wrote:
Quote:
je dois extraire un flottant codé sur 4 octets depuis un
fichier binaire,

En quel format ? XDR ?

Intel ou DEC. J'ai déjà les routines d'extraction de ce
flottant, que tu m'avais donné dans un fil précédent.

Il me semble qu'il y avait du déjà vu ici:-).

Quote:
que je dois convertir en entier non signé.

Avec quelles règles d'arrondi ? Où est-ce qu'on sait qu'a
priori, le flottant représente un entier dans l'intervale
représentable dans le type cible (int, long ?) ?

Le flottant représente un entier, positif de surcroit.

Et avec une valeur pas trop grande, j'espère. Convertir 1e300 en
entier, ça ne serait pas de la tarte.

Si on est sûr que ça ne déborde pas, la conversion est fournie
par le langage : static_cast< int >( unFloat ).

Quote:
Ensuite je dois extraire les bits de poids fort et faible
et récupérer ces deux valeurs...

Je ne suis pas sur ce que tu veux dire par là. A priori, si
tu as un int32_t, « ((uint32_t)(-1) << (32 - n)) & valeur »
récupère les n bits de poids forts. Alternativement, on
pourrait vouloir les avoir comme valeur, avec simplement «
valeur >> (32 - n) » (mais attention au comportement en cas
de valeur négative).

Récupérer le flottant, j'y arrive:

float IntelDataHandler::readFloat(std::ifstream & source ) const
{
uchar tmp[ 4 ] ;
if (!source.read(reinterpret_cast<char*>(tmp),4))
throw Exception("Impossible de lire le fichier");

float * f = (float *)tmp;
float flt = *f;

return flt;
}

Ça ne marche que si le flottant a été écrit par un programme
compilé avec la même version du même compilateur, compilé
avec les mêmes options, pour la même architecture. Et
encore... rien ne garantit que tmp soit correctement aligné
pour contenir un float.

J'ai testé avec plusieurs fichiers écrits par des machines x86
différentes, et ça marche tout le temps.

Qui l'a écrit n'est pas forcément la question -- on suppose
qu'ils ont pris les précautions pour l'écrire correctement. La
question est : où on le lit. Ce code ne fonctionnera sûrement
pas sur ma machine (un Sun Sparc, sous Solaris).

Quote:
Dans le cas de fichiers DEC, j'ai une autre routine adaptée,
que tu m'avais donné aussi je crois bien ;)

float DECDataHandler::readFloat(std::ifstream & source ) const
{
uchar tmp[ 4 ] ;
if (!source.read(reinterpret_cast<char*>(tmp),4))
throw Exception("Impossible de lire le fichier");

long mantis = (tmp[2] & 0xff) + ((tmp[3] & 0xffl) << Cool + (((tmp[0] &
0x7fl) | 0x80) << 16);
short exp = (tmp[1] & 0x7f) * 2 + ((tmp[0] & 0x80) ? 1 : 0);
if (tmp[1] & 0x80)
mantis = -mantis;

float flt = (mantis || exp) ? ((float) ldexp (mantis, (exp - 128 - 24)))
: 0;

return flt;
}

Personnellement, je ferais quelque chose de semblable pour
Intel. Pour le cas où je dois le compiler sur un processeur
autre qu'un 80x86. Il suffit en gros de changer les indices des
octets, et de soustraire 126 à la place de 128 de l'exposant.
Mais peut-être il faudrait aussi ajouter du code pour traiter
des dénormalisés, des infinités et des NaN.

Quote:
Et comment je peux extraire les deux données?

Est-ce que je ne peux tout simplement pas, au lieu de lire un
float, lire deux short, me donnant directement les bonnes
valeurs?

Certainement pas.

Est-ce que du coup, comme les float que je récupère via les
routines que j'ai données plus haut sont corrects, je peux
utiliser le code suivant donné par Fabien plus haut?

Si tu ne veux qu'un seul bit chaque fois, oui. Mais d'après ton
autre posting, et la description du protocol, je crois en fait
que ce que tu veux, c'est de convertir le flottant en short, et
puis prends les deux octets. Seulement, la description du
protocol n'est pas des plus claires : que signifie ici « first
byte » et « second byte » ? J'ai plutôt l'impression que ça
aussi dépend de l'encodage, et serait différent pour MIPS que
pour Intel et DEC (qui utilise le même format pour des short).
Pour Intel et DEC, on aurait :

short tmp = readFloat() ;
uchar camera = tmp & 0xFF ;
uchar residual = tmp >> 8 ;

Pour MIPS, inverser camera et scale.

Mais c'est encore assez vague à mon avis. Est-ce que scale est
signé ou non ? Et d'autre texte dans le document suggère que
peut-être byte 1 signifie l'octet de poids fort, et non le
premier octet. Sauf que dans ce cas-là, normalement, on
parlerait de byte 0 pour l'octet de poids faible. Au moins qu'on
a appris l'informatique chez IBM.

(Je ne sais pas qui a inventé ce format, mais il a l'air d'être
un des plus tordu que je n'ai jamais rencontré. À part,
peut-être, des virgules flottants en BER.)

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Back to top
Michael
Guest





PostPosted: Tue Mar 28, 2006 9:06 am    Post subject: Re: float => unsigned int et extraction bits poids fort Reply with quote

Quote:
Il me semble qu'il y avait du déjà vu ici:-).

En effet ;)

Quote:
Et avec une valeur pas trop grande, j'espère. Convertir 1e300 en
entier, ça ne serait pas de la tarte.

Non ce sont des "petites" valeurs, pas de soucis avec ça.

Quote:
Si on est sûr que ça ne déborde pas, la conversion est fournie
par le langage : static_cast< int >( unFloat ).

C'est ce que j'avais utilisé après coup.

Quote:
Qui l'a écrit n'est pas forcément la question -- on suppose
qu'ils ont pris les précautions pour l'écrire correctement. La
question est : où on le lit. Ce code ne fonctionnera sûrement
pas sur ma machine (un Sun Sparc, sous Solaris).

C'est un programme destiné à tourner sur Windows uniquement.

Quote:
Personnellement, je ferais quelque chose de semblable pour
Intel. Pour le cas où je dois le compiler sur un processeur
autre qu'un 80x86. Il suffit en gros de changer les indices des
octets, et de soustraire 126 à la place de 128 de l'exposant.
Mais peut-être il faudrait aussi ajouter du code pour traiter
des dénormalisés, des infinités et des NaN.

Tu m'en avais déjà parlé la dernière fois, et je n'ai pas encore eu le
temps de me pencher là dessus.

Quote:
Si tu ne veux qu'un seul bit chaque fois, oui. Mais d'après ton
autre posting, et la description du protocol, je crois en fait
que ce que tu veux, c'est de convertir le flottant en short, et
puis prends les deux octets. Seulement, la description du
protocol n'est pas des plus claires : que signifie ici « first
byte » et « second byte » ? J'ai plutôt l'impression que ça
aussi dépend de l'encodage, et serait différent pour MIPS que
pour Intel et DEC (qui utilise le même format pour des short).
Pour Intel et DEC, on aurait :

short tmp = readFloat() ;
uchar camera = tmp & 0xFF ;
uchar residual = tmp >> 8 ;

Ce code marche parfaitement, c'est exactement ça qu'il me faut...

Quote:
Mais c'est encore assez vague à mon avis. Est-ce que scale est
signé ou non ? Et d'autre texte dans le document suggère que
peut-être byte 1 signifie l'octet de poids fort, et non le
premier octet. Sauf que dans ce cas-là, normalement, on
parlerait de byte 0 pour l'octet de poids faible. Au moins qu'on
a appris l'informatique chez IBM.

(Je ne sais pas qui a inventé ce format, mais il a l'air d'être
un des plus tordu que je n'ai jamais rencontré. À part,
peut-être, des virgules flottants en BER.)

Je confirme. Pour la première fois où je dois lire dans un fichier
binaire, j'ai été gaté!

Encore merci pour vos lumières!
Back to top
kanze
Guest





PostPosted: Wed Mar 29, 2006 7:06 am    Post subject: Re: float => unsigned int et extraction bits poids fort Reply with quote

Michael wrote:

[...]
Quote:
Qui l'a écrit n'est pas forcément la question -- on suppose
qu'ils ont pris les précautions pour l'écrire correctement. La
question est : où on le lit. Ce code ne fonctionnera sûrement
pas sur ma machine (un Sun Sparc, sous Solaris).

C'est un programme destiné à tourner sur Windows uniquement.

Pour l'instant, en tout cas:-).

Mon expérience montre que ce genre de choses à une tendance à
évoluer. Dans la mesure où il existe une solution portable, je
le préfère.

Quote:
Personnellement, je ferais quelque chose de semblable pour
Intel. Pour le cas où je dois le compiler sur un processeur
autre qu'un 80x86. Il suffit en gros de changer les indices des
octets, et de soustraire 126 à la place de 128 de l'exposant.
Mais peut-être il faudrait aussi ajouter du code pour traiter
des dénormalisés, des infinités et des NaN.

Tu m'en avais déjà parlé la dernière fois, et je n'ai pas encore eu le
temps de me pencher là dessus.

Il y a des chances que ça n'a pas d'importance. Beaucoup dépend
d'où vient les données.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.