Page 1 sur 1

problème avec les réels et les opérations

Publié : jeu. 25/août/2005 12:27
par Dr. Dri
là j'avoue ne pas comprendre :lol:

Code : Tout sélectionner

a.f = Pow(2, 32)
Debug a
Debug a - 1.0
Debug a + 1.0
Dri

Publié : jeu. 25/août/2005 12:58
par lionel_om
C'est à cause du système de la virgule flottante :wink:
si tu met a + 1000, là il y aura une différence, qui sera sans doute mauvaise, mais bon.
C'est la même chose que qd on essaye de coder PI : 3.1415916... La valeur va être modifier selon le codage (les puissnaces de 2..)

J'espère être assez clair. :?

Publié : jeu. 25/août/2005 13:26
par Dr. Dri
mais là le nombre va bien jusqu'aux unités nan ?

Dri

Publié : jeu. 25/août/2005 14:06
par lionel_om
Bah non, pas forcément.
Etend donné que tu peut coder un nombre extrémenet grand comme extrément petit tu es limité :
Le codage s'effactue de la sorte : (en 32 bits)
* 1 bit pour le signe
* 8 bits pour l'exposant
* 23 bits pour la mantisse

Donc on a 23 bits pour la précisions (le bit du signe ne limitant rien)(les bits de l'exposant servant juste à définir la taille de la plage supportée).

Je vais essayé de te faire un exemple...
Lis ça en attendanat sinon : http://www.mines.inpl-nancy.fr/~tombre/ ... fo015.html

Publié : jeu. 25/août/2005 14:57
par lionel_om
J'arrive pas à voir les bits des float ... :?
J'y arrive avec les bytes/words/longs, ms pas avec les float :

Code : Tout sélectionner

Procedure.s ByteToBin(b.b)
  Protected s.s, i.b, pow.b
  
  s = "00000000"
  For i = 0 To 7
    pow = Pow(2,i)
    If b & pow
      PokeB(@s + (7-i), Asc("1"))
    EndIf
  Next
  ;Debug s
  ProcedureReturn s

EndProcedure


Procedure.s LongToBin(l.l)
  Protected s.s, i.w, pow.l
  
  s = "00000000000000000000000000000000"
  For i = 0 To 31
    pow = Pow(2,i)
    If l & pow
      PokeB(@s + (31-i), Asc("1"))
    EndIf
  Next
  ;Debug s
  ProcedureReturn s

EndProcedure



;a.f = Pow(2, 32)
;Debug a

a.l = 32767

Debug "Conversion de " + Str(a)
s.s
For i = 0 To 3
  s = ByteToBin(PeekB(@a + i)) + s
Next i

Debug s

Debug LongToBin(a)


; ***********************
; *   Partie Float !!!  *
; ***********************

; -------------------------- BUG !!! ------------------------


Debug " --- "

b.f = Pow(2,32)
Debug b

s = ""
For i = 0 To 3
  s = ByteToBin(PeekB(@b + i)) + s
Next i
Debug s



b.f = -13.125
Debug b

s = ""
For i = 0 To 3
  s = ByteToBin(PeekB(@b + i)) + s
Next i
Debug s


b.f = 1
Debug b

s = ""
For i = 0 To 3
  s = ByteToBin(PeekB(@b + i)) + s
Next i
Debug s


b.f = -1
Debug b

s = ""
For i = 0 To 3
  s = ByteToBin(PeekB(@b + i)) + s
Next i
Debug s
Il me met toujours els 16 derniers bits à "0", alors que les float PB sont bien sous 32 bits !!!
Bizarre, à moins que j'ai loupé qqchose !!!? :roll:

Publié : jeu. 25/août/2005 15:13
par Dr. Dri
pour voir les bits d'un Float, lis le comme un Long, ca doit être simple comme ca nan ?

Code : Tout sélectionner

*ptr.Long = @var.f
var = Pow(2, 32)
Debug Bin(*ptr\l)
Dri

Publié : jeu. 25/août/2005 15:31
par lionel_om
Non marche pas comme ça ! :cry:

Publié : jeu. 25/août/2005 22:54
par fweil

Code : Tout sélectionner

Procedure.s Debug_Float32(Address.f)
  Sign.l = PeekL(@Address) & $80000000
  If Sign : Sign = -1 : Else : Sign = 1 : EndIf
  Exponant.l = PeekL(@Address) & $07F80000
  Exponant.l = Exponant >> 23
  Mantissa.l = PeekL(@Address) & $007FFFFF
  Mantissa_Copy.l = Mantissa
  ProcedureReturn RSet(Hex(PeekL(@Address)), 8, "0") + " Sign : " + Str(Sign) + " Exponant : " +  RSet(Hex(Exponant), 2, "0") + " Mantissa : " + RSet(Hex(Mantissa), 6, "0")
EndProcedure

  fValue.f
  fValue = 0.0 : Debug StrF(fValue, 10) + " " + Debug_Float32(fValue)
  fValue = 1.0 : Debug StrF(fValue, 10) + " " + Debug_Float32(fValue)
  fValue = 2.0 : Debug StrF(fValue, 10) + " " + Debug_Float32(fValue)
  fValue = 3.14159265 : Debug StrF(fValue, 10) + " " + Debug_Float32(fValue)
  fValue = -3.14159265 : Debug StrF(fValue, 10) + " " + Debug_Float32(fValue)
  fValue = 31.4159265 : Debug StrF(fValue, 10) + " " + Debug_Float32(fValue)
  fValue = 31415.9265 : Debug StrF(fValue, 10) + " " + Debug_Float32(fValue)
  
End

Publié : ven. 26/août/2005 9:04
par lionel_om
:10:

Ce qui donne :

Code : Tout sélectionner

Procedure.s FloatToBin(Address.f)
  Protected Exponant.l, Mantissa.l, s.s, i.b, pow.l

  s = "00000000000000000000000000000000"
  If PeekL(@Address) & $80000000
    PokeB(@s, Asc("1"))
  EndIf
  
  Exponant.l = PeekL(@Address) & $07F80000
  Exponant.l = Exponant >> 23
  For i = 0 To 7
    pow = Pow(2,i)
    If Exponant & pow
      PokeB(@s + (8-i), Asc("1"))
    EndIf
  Next
  Mantissa.l = PeekL(@Address) & $007FFFFF
  For i = 0 To 20
    pow = Pow(2,i)
    If Mantissa & pow
      PokeB(@s + (31-i), Asc("1"))
    EndIf
  Next

  ProcedureReturn s
EndProcedure

Publié : ven. 26/août/2005 9:57
par fweil
lionel_om,

A 1 bit près.

Mais si c'est juste pour afficher les bits de la mantisse, il y a plus simple (Valeur est un flottant bien entendu) :

Debug RSet(Bin(PeekL(@Valeur) & $007FFFFF), 23, "0")

Publié : ven. 26/août/2005 12:06
par lionel_om
Oula, en fait c'était tout simple :

Code : Tout sélectionner

Procedure.s ByteToBin(b.b)
  Protected s.s, i.b, pow.b
  
  s = "00000000"
  For i = 0 To 7
    pow = Pow(2,i)
    If b & pow
      PokeB(@s + (7-i), Asc("1"))
    EndIf
  Next
  ;Debug s
  ProcedureReturn s

EndProcedure


Procedure.s LongToBin(l.l)
  Protected s.s, i.w, pow.l
  
  s = "00000000000000000000000000000000"
  For i = 0 To 31
    pow = Pow(2,i)
    If l & pow
      PokeB(@s + (31-i), Asc("1"))
    EndIf
  Next
  ;Debug s
  ProcedureReturn s

EndProcedure


Procedure.s FloatToBin(f.f)
  ProcedureReturn LongToBin(PeekL(@f))
EndProcedure
:10: ???

Publié : ven. 26/août/2005 12:10
par Dr. Dri
c'est pas ce ke je t'avais suggéré au-dessus ?

Dri tusors:

Publié : ven. 26/août/2005 13:05
par lionel_om
J'suis vraiment un boulet !!!
:jesors: :0: