Les conversions de base et les conversions byte à byte

Partagez votre expérience de PureBasic avec les autres utilisateurs.
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Les conversions de base et les conversions byte à byte

Message par PAPIPP »

Bonjour à tous

A la suite de ma recherche sur les nombres premiers et de la décomposition d’un nombre en facteurs premiers à la limite des possibilités de la machine,
je me suis trouver à rechercher les nombres premiers jusqu’à 2^64 = 18446744073709551616
c'est-à-dire le double de 2^63=9223372036854775808 et -1 c’est la limite qui existe actuellement.2^63-1

Comme en pb il n’existe pas de quad non signé il fallait développer une conversion de base 10 en base 16 et inversement de base 16 en base 10 jusqu’à la limite de 2^64 voire au dessus.

C’est la division euclidienne qui est à la base de l’algo que j’ai utilisé.

Voici les 2 prg qui permettent une conversion de base décimale en base hexa et inversement pour des nombre en base 10 de 0 à >>>10^20

Code : Tout sélectionner

 Macro _q_t_ 
 				" 
 EndMacro 
 Macro _n (__n) 
 _q_t_#__n#=_q_t_+Str(__n)+" " 
 EndMacro 
 Macro _Q (__Q) 
 _q_t_#__Q#=_q_t_+Str(__Q)+" " 
 EndMacro 
 Macro _s (__S)
 _q_t_#__S#=_q_t_+__S+" "
 EndMacro
Procedure.s HEX2DEC(HEXS.S)
  EnableExplicit
  Static Dim t_rest.a(1000)
  Protected DIVIDENDE$,vald.q,longt,resultat$,DIVIDP$,DIVIDPR$,QUOTP.q,RESTP.q,quotp$,j,ii,DIVIDP.Q,Irest
  DIVIDENDE$=LTrim(UCase(HEXS))
  vald.q=Val("$"+DIVIDENDE$)
  longt=Len(DIVIDENDE$)
  If vald>0 And longt<17
    resultat$=Str(vald)
  Else  
    Irest=0
    DIVIDP$=""
    DIVIDPR$=""
    quotp$=""
    Repeat 
      For ii=1 To longt
        DIVIDP$=DIVIDPR$+Mid(DIVIDENDE$,ii,1)
        DIVIDP.Q=Val("$"+DIVIDP$)
        ;   QUOTP.q=DIVIDP/10
        ;   RESTP.q=DIVIDP%10
        EnableASM
        MOV ax,word [p.v_DIVIDP]  
        MOV cl,10
        ;   idiv Cl 
        DIV cl  ; utilise moins de cycles machine que idiv
        MOV  [p.v_QUOTP],al
        MOV [p.v_RESTP],AH
        DisableASM
        
        DIVIDPR$=Hex(RESTP)
        quotp$+Hex(QUOTP)
      Next 
      t_rest(Irest)=RESTP
      Irest+1 
      DIVIDENDE$=QUOTP$
      longt=Len(DIVIDENDE$) 
      DIVIDP$=""
      DIVIDPR$=""
      quotp$=""
      
    Until Val("$"+ dividende$)=0
    For j=Irest-1 To 0 Step-1
      resultat$+Str( t_rest(j))
      t_rest(j)=0
    Next
  EndIf
  ProcedureReturn  resultat$
  DisableExplicit
EndProcedure

Procedure.s DEC2HEX(DECI.S)
  EnableExplicit
  Static Dim t_rest.a(1000)
  Protected DIVIDENDE$,vald.q,longt,resultat$,DIVIDP$,DIVIDPR$,QUOTP.q,RESTP.q,quotp$,i,j,ii,DIVIDP.Q,Irest
  DIVIDENDE$=UCase(DECI)
  longt=Len(DIVIDENDE$)
  If Val(DIVIDENDE$)=>0  And longt<20
    vald.q=Val(DIVIDENDE$)
    resultat$=Hex(vald)
  Else  
    irest=0
    DIVIDP$=""
    DIVIDPR$=""
    quotp$=""
    Repeat 
      For ii=1 To longt
        DIVIDP$=DIVIDPR$+Mid(DIVIDENDE$,ii,1)
        DIVIDP.Q=Val(DIVIDP$)
        ;   QUOTP.q=DIVIDP/16
        ;   RESTP.q=DIVIDP%16
        EnableASM
        MOV ax,word [p.v_DIVIDP]  
        MOV cl,16
        ;   div Cl 
        DIV Cl  ; utilise moins de cycles machine que idiv
        MOV  [p.v_QUOTP],al
        MOV [p.v_RESTP],AH
        DisableASM
        
        DIVIDPR$=Str(RESTP)
        quotp$+Str(QUOTP)
      Next 
      t_rest(Irest)=RESTP
      Irest+1 
      DIVIDENDE$=QUOTP$
      longt=Len(DIVIDENDE$) 
      DIVIDP$=""
      DIVIDPR$=""
      quotp$=""
      
    Until Val(dividende$)=0
    For j=Irest-1 To 0 Step-1
      resultat$+Hex( t_rest(j))
      t_rest(j)=0
    Next
  EndIf
  ProcedureReturn  resultat$
  DisableExplicit
EndProcedure
Define VALQ.q,HVALQ.s,DECIM.S,i,DECI.s,decip.s,HEX2$,HEX$,DECIM2$

OpenConsole()
; DECI.s="19223372036854775807"
DECI.s="9223372036854775800"
; DECIP.s=right(deci,len(deci)-2)
DECIP.s=Right(deci,Len(deci)-1)
; valq.q=val(DECIP)
valq.q=Val(decip)
; Hvalq.s="19"+str(valq)
For i=0 To 100
  ;   Hvalq.s="19"+str(valq)
  Hvalq.s="9"+Str(valq)
  HEX2$=DEC2HEX(HVALQ)
  DECIM.S = HEX2DEC(HEX2$)
  HEX$=DEC2HEX(DECIM)
  DECIM2$=HEX2DEC(HEX$)
  PrintN(_s(HVALQ)+_s(HEX2$)+_s(DECIM)+_s(HEX$)+_s(DECIM2$)+"        " +Hex(valq))
  valq+1
Next 
PrintN( "******************  nettement au dessus de  $7FFFFFFFFFFFFFFF ")
DECI.s="19223372036854775807"
; DECI.s="9223372036854775800"
DECIP.s=Right(deci,Len(deci)-2)
; DECIP.s=right(deci,len(deci)-1)
; valq.q=val(DECIP)
valq.q=Val(decip)
; Hvalq.s="19"+str(valq)
For i=0 To 100
  Hvalq.s="19"+Str(valq)
  ;   Hvalq.s="9"+str(valq)
  HEX2$=DEC2HEX(HVALQ)
  DECIM.S = HEX2DEC(HEX2$)
  HEX$=DEC2HEX(DECIM)
  DECIM2$=HEX2DEC(HEX$)
  PrintN(_s(HVALQ)+_s(HEX2$)+_s(DECIM)+_s(HEX$)+_s(DECIM2$)+_n(Len(decim2$))+"  " +Hex(valq))
  valq+1
Next 


Input()
CloseConsole()

Après quelques recherches sur le forum anglais, allemand et français J’ai trouvé des prg de conversion alpha byte à byte mais très peu de conversion de changement de base permettant la conversion des nombres >2^63 voire aucun.

Les conversions byte à byte dans la triangulation string hexa et binaire sont très différentes des conversions de base
des nombres entiers ( base 10) en hexa (base 16)

Exemple 789 un entier en base 10 vaut 315 en hexa base 16
Alors que la conversion byte à byte de 789 en hexa ascii 373839 et en unicode 370038003900

Autre exemple 2748 base 10 un entier qui vaut ABC en hexa base 16
Alors que la conversion byte à byte de 2748 en hexa ascii 32373438
et en unicode 3200370034003800
La représentation en machine en little-endian(Intel) de 2748 sera BC0A.et en big-endian (Mac-Os)la représentation sera 0ABC

Ce n’est pas trop facile de se repairer dans cet environnement.
Attention lorsque l’on parle de conversion en hexa soyez assez précis.

Voici le programme de conversion byte à byte.
Il permet de convertir une chaine de caractères alpha en chaine hexa ou binaire
__________Convertir une chaine Hexa en chaine caractères ou binaire
__________Convertir une chaine binaire en chaine hexa ou caractères
Les conversions seront limités par l(allocation mémoire à 2^20=1048576 octets ce qui nous donne en binaire
la représentation d’une chaine ascii de 131072 octets et de 65535 caractères en unicode.

Code : Tout sélectionner

Macro _q_t_ 
 	" 
 EndMacro 
 Macro _n (__n) 
 _q_t_#__n#=_q_t_+Str(__n)+" " 
 EndMacro 
 Macro _Q (__Q) 
 _q_t_#__Q#=_q_t_+Str(__Q)+" " 
 EndMacro 
 Macro _s (__S)
 _q_t_#__S#=_q_t_+__S+" "
 EndMacro

;  EnableExplicit
Structure S_X_cr ; S comme structure X comme dimmension inconnue et cr comme crochet []
  StructureUnion
    VA.a[0]   ; ascii
    VB.b[0]   ; byte
    VC.c[0]   ; character
    VS.s{1}[0]; String 1 Byte
    VS2.s{2}[0]; String 2 Bytes
    VS3.s{3}[0]; String 3 Bytes
    VS4.s{4}[0]; String 4 Bytes
    VS8.s{8}[0]; String 8 Bytes
    VSIL.S{1048576}[0]
    Vu.u[0]    ; unicode
    Vw.w[0]    ; word
    Vl.l[0]    ; long
    Vi.i[0]    ; integer
    Vq.q[0]    ; quad
    Vf.f[0]    ; float
    Vd.d[0]    ; double
  EndStructureUnion
EndStructure

Procedure.s CONV_STR_BIB_HEX_STR(*ADR.S_x_cr,LNG,ORIG.s="s",DEST.s="h")
  EnableExplicit 
  ; ORIG ET DEST donne les options de la procédure ORG pour origine et dest pour destination
  ; avec h or H -> Pour Hexa
  ; avec b or B -> Pour Binaire
  ; avec s or S -> pour String
  Enumeration  
    #REGEX1 
    #REGEX2
  EndEnumeration  
  
  
  Structure EL_h
    Bn.s{16}
    Hx.s{4}
    AA.s{2}
  EndStructure
  Structure tab_H
    Array el.el_H(256)
  EndStructure
  
  Static flag.b=0,TAB.tab_h,*adrs.S_x_cr,CHR$=Chr(0)+Chr(0);, *ADM.S_x_cr 
  
  Protected typ${1}="",rmp${1}="",pref${1}="",restl,ii,deplac,RET_ASC.s,num,mess$,valb$
  
  DEST=UCase(Left(Trim(DEST),1))
  ORIG=UCase(Left(Trim(ORIG),1))
  If flag=0
    ; ** Chargement de la table en accés directe
    For ii=0 To 255
      If #PB_Compiler_Unicode = 1 ; And orig= "S" ;;; Si nous sommes sous unicode et origine string
        tab\el(ii)\bn=RSet(Bin(ii,#PB_Unicode),8,"0")
        tab\el(ii)\Hx=RSet(Hex(ii,#PB_Unicode),2,"0")
      Else
        tab\el(ii)\bn=RSet(Bin(ii,#PB_Ascii),8,"0")
        tab\el(ii)\Hx=RSet(Hex(ii,#PB_Ascii),2,"0")
      EndIf
      tab\el(ii)\AA=Chr(ii)
    Next
    flag+1
    If  Not CreateRegularExpression(#regex1,"[^0-9a-fA-F]+")
      ; If  Not CreateRegularExpression(#regex1,"[^:h]+") ;;; n'est pas bon
      MessageRequester("ATTENTION REGEX1 NON CREE", RegularExpressionError())
    EndIf  
    If  Not CreateRegularExpression(#regex2,"[^0-1]+")
      MessageRequester("ATTENTION REGEX2 NON CREE", RegularExpressionError())
    EndIf  
    
    
  EndIf
  Define *ADM.S_x_cr 
;   *ADM=AllocateMemory(131072) 
    *ADM=AllocateMemory(1048576) 
  ; **** Contrôles de l'entrée en hEXA et en Binaire et Chargement de la table en accés directe
  
  Select orig
    Case  "H"
      restl=LNG%2
      If restl>0
        *ADM\VC[0]=$32
        If #PB_Compiler_Unicode = 1 ; 
          CopyMemory(*ADR,*ADM+2,LNG*2)
;           ShowMemoryViewer(*ADM,256)
          LNG+1
        Else  
          CopyMemory(*ADR,*ADM+1,LNG*2)
;           ShowMemoryViewer(*ADM,256)
          LNG+1
        EndIf  
      Else
        CopyMemory(*ADR,*ADM,lng*2)
      EndIf
    Case  "B" 
      restl=LNG%8
      If restl>0
        deplac=8-restl
        *ADM\VSIL=ReplaceString(Space(deplac)," ","0")
        If #PB_Compiler_Unicode = 1 ;
          CopyMemory(*ADR,*ADM+deplac*2,LNG*2)
;           ShowMemoryViewer(*ADM,256)
          LNG+deplac
        Else  
          CopyMemory(*ADR,*ADM+Deplac,LNG*2)
;           ShowMemoryViewer(*ADM,256)
          LNG+DEPLAC
        EndIf  
        ;         CopyMemory(*ADR,*ADM,LNG*2)
      Else
        CopyMemory(*ADR,*ADM,lng*2)
      EndIf
    Case "S" 
      CopyMemory(*ADR,*ADM,lng*2)
      
    Default
      ;       *ADM\VSIL=*ADR\VSIL
      CopyMemory(*ADR,*ADM,lng*2)
;       Debug *ADM\VSIL[0]
  EndSelect     
  ;****************** Selection de la structure d'ORIGine String Hexa ou Binaire **********************************
  Select ORIG 
    Case "S"  ;;; origine string 
      If DEST="B"
        RET_ASC.s=""
        For ii=0 To lng-1
          RET_ASC+tab\el(*ADM\VC[ii])\Bn
        Next 
      Else
        RET_ASC.s=""
        For ii=0 To lng-1
          num=*ADM\VC[ii]
          RET_ASC+tab\el(*ADM\VC[ii])\Hx
        Next 
      EndIf
    Case "B"  ;;; origine Binaire 
      If ExamineRegularExpression(#regex2, *ADM\VSIL[0])
        mess$=""
        While NextRegularExpressionMatch(#REGEX2)
          mess$="Match: " + RegularExpressionMatchString(#REGEX2)+#CR$
          mess$+ " Position: " + Str(RegularExpressionMatchPosition(#REGEX2))+#CR$
          mess$+ " Longueur: " + Str(RegularExpressionMatchLength(#REGEX2))
        Wend
        If Len(mess$)>10
          MessageRequester("Zone non binaire",mess$)
        EndIf  
      EndIf
      
      If DEST="S"
        RET_ASC.s=""
        For ii=0 To lng/8-1 
          valb$=*ADM\VS8[ii]
          Num=Val("%"+valb$)
          ;           RET_ASC+Chr(NUM)
          RET_ASC+tab\el(num)\AA
        Next 
        ;         ProcedureReturn RET_ASC 
      Else
        RET_ASC.s=""
        For ii=0 To lng/8-1
          valb$=*ADM\VS8[ii]
          Num=Val("%"+valb$)
          RET_ASC+tab\el(num)\Hx
        Next 
        ret_asc+Chr(00)+Chr(00)
        ;         ProcedureReturn RET_ASC
      EndIf  
    Case "H"  ;;; origine Hexa 
      If ExamineRegularExpression(#regex1, *ADM\VSIL[0])
        mess$=""
        While NextRegularExpressionMatch(#REGEX1)
          mess$="Match: " + RegularExpressionMatchString(#REGEX1)+#CR$
          mess$+ " Position: " + Str(RegularExpressionMatchPosition(#REGEX1))+#CR$
          mess$+ " Longueur: " + Str(RegularExpressionMatchLength(#REGEX1))
        Wend
        If Len(mess$)>10
          MessageRequester("Zone non HEXA",mess$)
        EndIf  
      EndIf
      
      If DEST="S"
        RET_ASC.s=""
        For ii=0 To lng/2-1 
          valb$=*ADM\VS2[ii]
          Num=Val("$"+valb$)
          ;           RET_ASC+Chr(NUM)
          RET_ASC+tab\el(num)\AA
        Next
        ret_asc+Chr(00)+Chr(00)
        ;         ProcedureReturn RET_ASC 
      Else
        RET_ASC.s=""
        For ii=0 To lng/2-1
          valb$=*ADM\VS2[ii]
          Num=Val("$"+valb$)
          RET_ASC+tab\el(num)\Bn
        Next 
      EndIf  
  EndSelect 
  FreeMemory(*ADM) 
  ProcedureReturn RET_ASC+chr$
  DisableExplicit
EndProcedure
A$="2748"
hex2748$=CONV_STR_BIB_HEX_STR(@A$,len(A$),"S","H")
debug _s(A$)+_s(HEX2748$)
bin2748$=CONV_STR_BIB_HEX_STR(@A$,len(A$),"S","B")
debug _s(A$)+_s(BIN2748$)
A2748$=CONV_STR_BIB_HEX_STR(@bin2748$,len(BIN2748$),"B","S")
debug _s(A2748$) 
; NOM$="Durant Paul 3 rue BelleVille XYZW"
; NOMC$=""
; lenn=Len(NOM$)
; ; Debug mp_h(@nom$,256,220)
; Debug _s(NOM$)+_n(Len(nom$))
; HEX$=CONV_STR_BIB_HEX_STR(@NOM$,lenn,"S","H,")
; ; Debug mp_h(@HEX$,256,220)
; Debug _s(HEX$)+_n(Len(HEX$))
; BIN$=CONV_STR_BIB_HEX_STR(@Nom$,lenn,"S","B,")
; ; Debug mp_h(@BIN$,512,220)
; Debug _s(bin$)+_n(Len(bin$))
; str$= CONV_STR_BIB_HEX_STR(@bin$,Len(bin$),"B","S")
; ; Debug mp_h(@STR$,256,220)
; Debug _s(str$)+_n(Len(str$))
; HEX2$= CONV_STR_BIB_HEX_STR(@BIN$,Len(bin$),"B","H")
; ; Debug mp_h(@HEX$,256,220)
; Debug _s(HEX2$)+_n(Len(HEX2$))
; str2$= CONV_STR_BIB_HEX_STR(@HEX$,Len(HEX$),"H","S")
; ; Debug mp_h(@STR2$,256,220)
; Debug _s(str2$)+_n(Len(HEX$))
; BIN2$= CONV_STR_BIB_HEX_STR(@HEX$,Len(HEX$),"H","B")
; ; Debug mp_h(@BIN2$,512,220)
; Debug _s(BIN2$)+_n(Len(bin$))
; Debug "******************** essai avec les chaines hexa impaires et des chaines binaires non multiple de 8"
; CHAINE$=" Pierre"
; Debug _s(CHAINE$)+_n(Len(chaine$))
; HEX3$=CONV_STR_BIB_HEX_STR(@CHAINE$,Len(CHAINE$),"S","H")
; Debug _s(HEX3$)+_n(Len(HEX3$))
; BIN3$=CONV_STR_BIB_HEX_STR(@CHAINE$,Len(CHAINE$),"S","B")
; Debug _s(BIN3$)+_n(Len(bin3$))
; HEX3$="0506965727265"
; Debug _s(HEX3$)+_n(Len(HEX3$))
; str3$=CONV_STR_BIB_HEX_STR(@HEX3$,Len(HEX3$),"H","S")
; Debug _s(str3$)+_n(Len(str3$))
; ; BIN3$ = "00100000010100000110100101100101011100100111001001100101"
; BIN4$=   "100000010100000110100101100101011100100111001001100101"
; Debug _s(bin4$)+_n(Len(bin4$))
; STR4$=CONV_STR_BIB_HEX_STR(@BIN4$,Len(BIN4$),"B","S")
; Debug _s(STR4$)+_n(Len(STR4$))



A+
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Avatar de l’utilisateur
Kwai chang caine
Messages : 6962
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Les conversions de base et les conversions byte à byte

Message par Kwai chang caine »

Je comprend pas grand chose,, mais tout ce que tu écrits, est beau 8O
C'est plus de la programmation, mais de l'art.
Merci de partager ta grande connaissance 8)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Répondre