Besoin de conseils pour convertir des réels en binaire 32bits

Signaler
-
 Yulahop -
Bonjour a tous,

J'aurais besoin de conseils pour le problème suivant :

J'ai un fichier texte où sont stockées des nombres à virgule (réels) selon le format ascii grid et qui correspond à une image raster.
Les données correspondent à une matrice nb lignes x nb colonnes (valeurs connues).
Je souhaite ré-écrire ces données dans un fichier binaire sous la forme de nombre à virgule flottante au format IEEEE 754 lsbfirst 32 bits.

J'ai vu sur différents forum et sites le principe du format IEEE 32 bits (signe + exposant + mantisse) et la façon de passer des valeurs réelles décimales aux valeurs flottante.

Je souhaiterais avoir qq conseils pour l'écriture d'un code VB qui lise mon fichier texte en entrée et qui me génére un fichier binaire (*.flt) en sortie.

Voici les points sur lesquels je sollicite vos remarques :

- ouverture du fichier binaire avec l'instruction open for binary
- pour chaque réel du fichier texte, je pense faire un algo qui me génère la succession des 32 valeurs binaires
en décomposant les parties entière et décimale (division euclidienne, méthode expliquée sur les forums,...) pour obtenir l'exposant et la mantisse
- écriture dans le fichier binaire avec l'instruction Put pour écrire les 32 bits.

Là, il y a un truc qui m'échappe pour l'écriture, est ce que je dois écrire bit par bit ?
Quelles instructions utiliser ? (Put ?)
LSBFIRST ? je dois commencer par écrire le dernier bit de la mantisse ?


Merci pour vos remarques et conseils

Salutations !

Yul

7 réponses

Messages postés
3258
Date d'inscription
jeudi 26 novembre 2009
Statut
Membre
Dernière intervention
3 décembre 2019
50
Salut

Codes tu bien en vb6 microsoft visualbasic 6.0 ?
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
74
Salut

"succession des 32 valeurs binaires"
Dans quoi sont-elles stockées ?
Dans un Long ?
Dans ce cas, il suffit d'écrire ce Long :
Put #NoFichier, , maVarLong
Les deux virgules qui se suivent veulent dire qu'on ne spécifie pas d'adresse et que l'écriture se faire à l'emplacement actuel du pointeur, c'est à dire à la fin des données actuelles.

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on le partage (Socrate)
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
74
PS : En VB, il n'existe pas de type de variable 'binaire'.
En fait, il est plus simple de travailler avec un entier (Long dans ton cas) et de jouer avec les Or pour activer ou les And et - (moins) pour désactiver un des bits du mot.

Exemples :
Si tu veux activer le 6ème bit (c'est à dire le bit 5) d'un Long :
monLong = monLong Or (2^5)
Pour désactiver le 12ème bit (donc le 11) :
If monLong And (2^11) (2^11) Then monLong monLong - (2^11)
Bonjour,

ShayW, je code avec VB6.

Jack,
Est ce que je comprend bien : j'utilise un Long dans lequel je vais activer/désactiver les 32 bits pour que la séquence finale correspondent au codage IEEEE de ma valeur réelle entrée ?
Je commence par déterminer la séquence codant ma valeur réelle (signe+exposant+mantisse) ;
je transcrit cette séquence dans un long avec une série (32 en fait) de AND et OR ;
j'écris le résultat en sortie.
Messages postés
3258
Date d'inscription
jeudi 26 novembre 2009
Statut
Membre
Dernière intervention
3 décembre 2019
50
Salut

après avoir lu un tutoriel
ici

un code pour convertir en format IEEE354 32 bits
je n'ai pas vraiment testé
Private Function ConvertToIEEE754(n As String) As Long
  Dim res As Long
  Dim value As Double
  Dim exponent As Integer
  res = 0
  If Val(n) < 0 Then
   'change bit 32 to 1
   res = res Or &H80000000
  End If
   value = Abs(Val(n))
   exponent = 127
    p = InStr(1, CStr(value), ".")
   If value >= 1 Then
  While Val(Mid(CStr(value), 1, p - 1)) > 1
       value = value / 2
       p = InStr(1, CStr(value), ".")
       exponent = exponent + 1
    Wend
     
   End If
  
    If value < 1 Then
    
     While Val(Mid(CStr(value), 1, p - 1)) < 1
       value = value * 2
        p = InStr(1, CStr(value), ".")
       exponent = exponent - 1
    Wend
    End If
    SetExponent exponent, res
  
    value = value - 1
    SetMantissa value, res
    
End Function
 
Private Sub SetExponent(numbase10 As Integer, ByRef res As Long)
 Dim digit As Integer
 
 Dim count As Integer
 count = 0
 While numbase10 > 0
   digit = numbase10 Mod 2
   If digit = 1 Then
    res = res Or (2 ^ (23 + count))
    End If
    count = count + 1
   numbase10 = numbase10 \ 2
 Wend
 
 End Sub
 Private Sub SetMantissa(dec As Double, ByRef res As Long)
   Dim count As Integer
   count = 0
   While count < 23 And dec <> 1
    dec = dec * 2
    If dec - 1 > 0 Then
      res = res Or (2 ^ count)
    End If
      count = count + 1
      If dec > 1 Then
       dec = dec - 1
      End If
    Wend
End Sub
Messages postés
3258
Date d'inscription
jeudi 26 novembre 2009
Statut
Membre
Dernière intervention
3 décembre 2019
50
tout le code est faut
un code amélioré

Private Function ConvertToIEEE754(n As String) As Long
  Dim res As Long
  Dim value As Double
  
  Dim exponent As Integer
  res = 0
  If Val(n) < 0 Then
   'change bit 32 to 1
   res = res Or &H80000000
  End If
   value = Abs(Val(n))
   exponent = 127
   If value >= 1 Then
      While value / 2 > 1
       value = value / 2
        exponent = exponent + 1
      Wend
    Else
    While value < 1
       value = value * 2
        exponent = exponent - 1
    Wend
   End If
  SetExponent exponent, res
  value = value - 1
    SetMantissa value, res
    ConvertToIEEE754 = res
End Function
 
Private Sub SetExponent(numbase10 As Integer, ByRef res As Long)
 Dim digit As Integer
 
 Dim count As Integer
 count = 0
 While numbase10 > 0
   digit = numbase10 Mod 2
   If digit = 1 Then
    res = res Or (2 ^ (23 + count))
    End If
    count = count + 1
   numbase10 = numbase10 \ 2
 Wend
 
 End Sub
 Private Sub SetMantissa(dec As Double, ByRef res As Long)
   Dim count As Integer
   count = 22
   While count >= 0 And dec <> 1
    dec = dec * 2
    If dec - 1 >= 0 Then
      res = res Or (2 ^ count)
    End If
      count = count - 1
      If dec > 1 Then
       dec = dec - 1
      End If
    Wend
End Sub
Hey !

Merci ShayW,
je vais me pencher dessus plus en détail