Nombres Grand Format (x86)

Programmation d'applications complexes
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Nombres Grand Format (x86)

Message par Micoute »

J'espère que ça va plaire à quelqu'un, ce programme a été inspiré par Lord Nelson qui adore les grands nombres et ça fait 2 ans que je le peaufine, j'ai donc décider, puisqu'on est dans la période des étrennes de vous en faire profiter.

n'hésitez pas à formuler des critiques quelles soient positives ou négatives, car c'est dans l'erreur qu'on progresse !

Code : Tout sélectionner

; DefineNGF - Nombre Grand Format

#NGFDim=10000
#Decimales_Defaut=0.001

Structure NGF
  Longueur.w
  Signe.w
  Nombre.i[#NGFDim]
EndStructure

; Signes
#NGFNegatif=1
#NGFPositif=0

; Types erreur (Longueur-champ)
#NGFIndefini=-1
#NGFInfinitif=-2
#NGFDepassement=-3
#NGFNonMisEnOeuvre=-4

; Dimensions
#NGFLongueur=9
#NGFMod=1000000000

Declare.s Afficher(*Nombre.NGF)          ;String
Declare NbreVersChaine(*Chaine.String,*Nombre.NGF) ;Chaine <- Nombre
Declare ChaineVersNbre(*Chaine,*Nombre.NGF)        ;Chaine -> Nombre

Declare NGFNormaliser(*a.NGF)              ;a = (a)
Declare NGFErreur(type,stype,*a.NGF)       ;c = Err
Declare NGFCopier(*a.NGF,*b.NGF)           ;b = a
Declare NGFZero(*a.NGF)                    ;a = 0
Declare NGFAbs(*a.NGF)                     ;a = |a|

Declare NGFMu10(*a.NGF,b.i,*c.NGF)         ;c = a*b, |b|<10^10
Declare NGFMultiplier(*a.NGF,*b.NGF,*c.NGF);c = a*b
Declare NGFDiviser(*a.NGF,*b.NGF,*c.NGF)   ;c = a/b
Declare NGFDi10(*a.NGF,b.i,*c.NGF)         ;c = a/b, |b|<10^10
Declare NGFAjouter(*a.NGF,*b.NGF,*c.NGF)   ;c = a+b
Declare NGFSoustraire(*a.NGF,*b.NGF,*c.NGF);c = a-b
Declare NGFCarre(*a.NGF)                   ;a = a*a
Declare NGFPuissance(*a.NGF,b.i,*c.NGF)    ;c = a^b

Declare.i NGFPlusGrand(*a.NGF,*b.NGF,abs=0); a>b? ou |a|>|b|?
Declare.i NGFEgal(*a.NGF,*b.NGF,abs=0)     ; a=b? ou |a|=|b|?
Declare.i NGFPositif(*a.NGF)               ; a>=0?

Global NGF_Cache_A.NGF
Global NGF_Cache_B.NGF
Global NGF_Cache_C.NGF

Procedure.s Afficher(*Nombre.NGF) ;String
  Protected n
  Protected Texte.s
  
  If *Nombre\Longueur<0
    Select *Nombre\Longueur
      Case #NGFIndefini
        Texte="Indéfini"
      Case #NGFInfinitif
        Texte="Infinitif"
        If *Nombre\Signe
          Texte="Moins "+Texte
        EndIf
      Case #NGFDepassement
        Texte="Dépassement"
      Case #NGFNonMisEnOeuvre
        Texte="Non mis en oeuvre"
    EndSelect
  Else
    If *Nombre\Signe
      Texte="-"
    EndIf
    n=*Nombre\Longueur
    Texte+Str(*Nombre\Nombre[n])
    While n>0
      n-1
      Texte+RSet(Str(*Nombre\Nombre[n]),#NGFLongueur,"0")
    Wend
  EndIf
  ProcedureReturn Texte
EndProcedure

Procedure NbreVersChaine(*Chaine.String,*Nombre.NGF) ;Chaine <- Nombre
                                                        ; AVERTISSEMENT! s est de type String dans cette routine!
                                                        ; (Cela signifie que si x.string appèle "NbreVersChaine(x,Nombre)" la sortie sera "Debug x\s")
  
  Protected n
  Protected Texte.s
  
  If *Nombre\Signe
    Texte="-"
  EndIf
  n=*Nombre\Longueur
  Texte+Str(*Nombre\Nombre[n])
  While n>0
    n-1
    Texte+RSet(Str(*Nombre\Nombre[n]),#NGFLongueur,"0")
  Wend
  *Chaine\s=Texte
EndProcedure

Procedure ChaineVersNbre(*Chaine.String,*Nombre.NGF)  ;Chaine -> Nombre
  Protected n,p
  Protected Texte.s
  
  *Nombre\Signe=#NGFPositif
  Texte=PeekS(@*Chaine)
  n=Len(Texte)-#NGFLongueur
  
  While n>0
    *Nombre\Nombre[p]=Val(PeekS(@Texte+n,#NGFLongueur))
    p+1
    n-#NGFLongueur
  Wend
  n=Val(PeekS(@Texte,9+n))
  If n<0
    *Nombre\Signe=#NGFNegatif
    n=-n
  EndIf
  *Nombre\Nombre[p]=n
  *Nombre\Longueur=p
EndProcedure

Procedure NGFNormaliser(*a.NGF) ;a = (a) -a = a
                                   ; Boucle contenant les zéros (000.000.000)
  If *a\Longueur>=0
    While (*a\Longueur>=0) And (*a\Nombre[*a\Longueur]=0)
      *a\Longueur-1
    Wend
    ; Valeur égale à zéro? signe positif
    If *a\Longueur<0
      *a\Longueur=0
      *a\Signe=#NGFPositif
    EndIf
  EndIf
EndProcedure

Procedure NGFErreur(type,stype,*a.NGF) ;c = Err
  If type>=0
    type=stype
  EndIf
  Debug "ERREUR "+Str(type)
  *a\Longueur=type
EndProcedure

Procedure NGFCopier(*a.NGF,*b.NGF) ;b = a
  Protected n
  
  n=*a\Longueur
  *b\Longueur=n
  *b\Signe=*a\Signe
  While n>=0
    *b\Nombre[n]=*a\Nombre[n]
    n-1
  Wend
EndProcedure

Procedure NGFZero(*a.NGF) ;a = 0
  *a\Longueur=0
  *a\Signe=#NGFPositif
  *a\Nombre[0]=0
EndProcedure

Procedure NGFAbs(*a.NGF) ;a = |a|
  *a\Signe=#NGFPositif
EndProcedure

Procedure.i NGFEgal(*a.NGF,*b.NGF,abs=0)
  Protected n
  
  If n<>*b\Longueur
    ProcedureReturn #False
  ElseIf (abs=0) And (*a\Signe<>*b\Signe)
    ProcedureReturn #False
  Else
    While n>=0
      If *a\Nombre[n]<>*b\Nombre[n]
        ProcedureReturn #False
      EndIf
      n-1
    Wend
    ProcedureReturn #True;    a=b
  EndIf
EndProcedure

Procedure.i NGFPlusGrand(*a.NGF,*b.NGF,abs=0) ; a>b? ou |a|>|b|?
  Protected n,Difference
  
  If abs=0
    If *a\Signe<>*b\Signe
      If *a\Signe=#NGFPositif
        ProcedureReturn #True
      Else
        ProcedureReturn #False
      EndIf
    EndIf
  Else
    n=*a\Longueur
    If n>*b\Longueur
      ProcedureReturn #True
    ElseIf n<*b\Longueur
      ProcedureReturn #False
    Else
      While n>=0
        Difference=*a\Nombre[n]-*b\Nombre[n]
        If Difference>0
          ProcedureReturn #True ; a>b
        ElseIf Difference<0
          ProcedureReturn #False ; a<b
        EndIf
        n-1
      Wend
      ProcedureReturn #False;    a=b
    EndIf
  EndIf
EndProcedure

Procedure.i NGFPositif(*a.NGF) ; a>=0?
  If *a\Signe=#NGFPositif
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
EndProcedure

Procedure NGFMu10(*a.NGF,b.i,*c.NGF) ;c = a*b, |b|<10^10
  Protected n
  Protected m.q
  
  n=*a\Longueur
  If n<0
    NGFErreur(n,0,*c.NGF)
  Else
    If b=0
      *c\Longueur=0
      *c\Signe=#NGFPositif
      *c\Nombre[0]=0
    Else
      If b<0
        b=-b
        *c\Signe=#NGFNegatif-*a\Signe
      Else
        *c\Signe=*a\Signe
      EndIf
      n=0
      Repeat
        m+*a\Nombre[n] * b
        *c\Nombre[n]=m%#NGFMod
        m/#NGFMod
        n+1
      Until n>*a\Longueur
      If m
        *c\Nombre[n]=m
      Else
        n-1
      EndIf
      *c\Longueur=n
    EndIf
  EndIf
EndProcedure

Procedure NGFMultiplier(*a.NGF,*b.NGF,*c.NGF) ;c = a*b
  Protected la
  Protected lb
  Protected n
  Protected s.q
  Protected z.q
  If (*a\Longueur<0) Or (*b\Longueur<0)
    NGFErreur(*a\Longueur,*b\Longueur,*c.NGF)
  Else
    *c\Signe=(*a\Signe + *b\Signe)&1;    parce que #NGFNegatif=1
    *c\Longueur=*a\Longueur+*b\Longueur+1
    For n=0 To *c\Longueur
      *c\Nombre[n]=0
    Next n
    la=0
    Repeat
      lb=0
      z=*b\Nombre[lb]
      Repeat
        s=*a\Nombre[la] * *b\Nombre[lb] + *c\Nombre[la+lb]
        *c\Nombre[la+lb]=s%#NGFMod
        *c\Nombre[la+lb+1]+s/#NGFMod
        lb+1
      Until lb>*b\Longueur
      la+1
    Until la>*a\Longueur
    NGFNormaliser(*c)
  EndIf
EndProcedure

Procedure NGFDi10(*a.NGF,b.i,*c.NGF) ;c = a/b, |b|<10^10
  Protected n
  Protected d.q,q.q
  
  n=*a\Longueur
  If n<0
    NGFErreur(n,0,*c.NGF)
  Else
    If b=0
      *c\Longueur=#NGFIndefini
    Else
      If b<0
        b=-b
        *c\Signe=#NGFNegatif-*a\Signe
      Else
        *c\Signe=*a\Signe
      EndIf
      Repeat
        d=d*#NGFMod+*a\Nombre[n]
        q=d/b
        *c\Nombre[n]=q
        d-q*b
        n-1
      Until n<0
      NGFNormaliser(*c)
    EndIf
  EndIf
EndProcedure

Procedure NGFDiviser(*a.NGF,*b.NGF,*c.NGF) ;c = a/b
  Protected n
  
  If (*a\Longueur<0) Or (*b\Longueur<0)
    NGFErreur(*a\Longueur,*b\Longueur,*c.NGF)
  Else
    n=*b\Longueur
    If n=0
      If *b\Nombre[0]=0
        *c\Longueur=#NGFIndefini
      Else
        ;Debug "Di10"
        NGFDi10(*a.NGF,*b\Nombre[0],*c.NGF)
        *c\Signe=-(1&(*a\Signe+*b\Signe))
      EndIf
    Else
      If NGFPlusGrand(*b,*a,#True)
        NGFZero(*c)
      Else
        ; Hmmm... je vois pas trop
      EndIf
    EndIf
  EndIf
EndProcedure

Procedure NGFAjouter(*a.NGF,*b.NGF,*c.NGF) ;c = a+b
  Protected n
  Protected s
  
  If (*a\Longueur<0) Or (*b\Longueur<0)
    NGFErreur(*a\Longueur,*b\Longueur,*c.NGF)
  Else
    If *a\Signe<>*b\Signe
      ;Debug "Soustraire"
      *b\Signe=*a\Signe
      NGFSoustraire(*a.NGF,*b.NGF,*c.NGF)
    Else
      *c\Signe=*a\Signe
      If *a\Longueur<*b\Longueur
        Swap *a,*b
      EndIf
      While n<=*a\Longueur
        s+*a\Nombre[n]
        If n<=*b\Longueur
          s+*b\Nombre[n]
        EndIf
        *c\Nombre[n]=s%#NGFMod
        s/#NGFMod
        n+1
      Wend
      If s
        *c\Nombre[n]=s
      Else
        n-1
      EndIf
      *c\Longueur=n
    EndIf
  EndIf
EndProcedure

Procedure NGFSoustraire(*a.NGF,*b.NGF,*c.NGF) ;c = a-b
  Protected n
  Protected s
  
  If (*a\Longueur<0) Or (*b\Longueur<0)
    NGFErreur(*a\Longueur,*b\Longueur,*c.NGF)
  Else
    If *a\Signe<>*b\Signe
      ;Debug "Ajouter"
      *b\Signe=*a\Signe
      NGFAjouter(*a.NGF,*b.NGF,*c.NGF)
    Else
      If NGFPlusGrand(*a.NGF,*b.NGF,#True)
        *c\Signe=*a\Signe
      Else
        ;Debug "swap"
        Swap *a,*b
        *c\Signe=#NGFNegatif-*a\Signe
      EndIf
      While n<=*a\Longueur
        s+*a\Nombre[n]
        If n<=*b\Longueur
          s-*b\Nombre[n]
        EndIf
        If s<0
          *c\Nombre[n]=s+#NGFMod
          s=-1
        Else
          *c\Nombre[n]=s
          s=0
        EndIf
        n+1
      Wend
      *c\Longueur=n-1
      NGFNormaliser(*c)
    EndIf
  EndIf
EndProcedure

Procedure NGFCarre(*a.NGF) ;a = a*a
  If *a\Longueur>=0
    NGFMultiplier(*a,*a,NGF_Cache_C)
    NGFCopier(NGF_Cache_C,*a)
  EndIf  
EndProcedure

Procedure NGFPuissance(*a.NGF,b.i,*c.NGF) ;c = a^b
  Protected z=0,s,Signe
  If b<0
    ; a^b | b<0 n'est pas mis en œuvre pour l'instant...donc pas de puissance négative
    NGFErreur(#NGFNonMisEnOeuvre,0,*c.NGF)
  ElseIf *a\Longueur>=0
    NGFCopier(*a,NGF_Cache_A)
    ChaineVersNbre(@"1",NGF_Cache_B)
    If NGFPositif(*a)=#False
      NGFAbs(NGF_Cache_A)
      If b&1 :NGF_Cache_B\Signe=#NGFNegatif : EndIf
    EndIf
    While b>0
      s=1<<z
      If b&s
        NGFMultiplier(NGF_Cache_A,NGF_Cache_B,NGF_Cache_C)
        NGFCopier(NGF_Cache_C,NGF_Cache_B)
        b-s
      EndIf
      If b
        NGFCarre(NGF_Cache_A)
        z+1
      EndIf
    Wend
    NGFCopier(NGF_Cache_B,*c)
  EndIf
  
EndProcedure


; Nom: GrandDecimal
; Description: Calcul avec des nombres infiniment grands et exacts
; Micoute le 26 mai 2012


#GDLongueurMaxi = 1000000000
#GDNbreChiffres = 9

#GDExpNull = 0
#GDExpNaN  = 1
#GDExpInf  = 2

Global Dim GDMultiExp.i(#GDNbreChiffres-1)


Enumeration 0
  #GDArrondiInferieur     ; arrondir à 0
  #GDArrondiSuperieur     ; écart de l'arrondi à 0
  #GDArrondiPlafond       ; arrondi à Infinity
  #GDArrondiPlancher      ; arrondi à -Infinity
  #GDArrondiDemiInferieur ; arrondi au nombre entier inférieur (arrondi 0,5 à 0)
  #GDArrondiDemiSuperieur ; arrondi au nombre entier supérieur (arrondi 0 à 0,5)
EndEnumeration

Structure GrandDecimal
  sgn.b  ; Signe
  exp.i  ; Multiplier par le nombre (10 ^ 9) ^ exp
  taille.i ; Combien dans la mantisse
  Array man.i(1) ; Mantisse
EndStructure

; Signes
#GDNegatif=1
#GDPositif=0

Declare GDAdd(*GDa.GrandDecimal, *GDb.GrandDecimal, *resultat.GrandDecimal, nGDDecimales=#PB_Default)
Declare GDSub(*GDa.GrandDecimal, *GDb.GrandDecimal, *resultat.GrandDecimal, nGDDecimales=#PB_Default)
Declare GDdeQuad(quad.q, *resultat.GrandDecimal)


Global GDModeArrondi
Global GDValeurSpecialeUnNegatif.GrandDecimal
Global Dim GDValeurSpeciale.GrandDecimal(10)


; Méthode d'initialisation (pour Tailbite)
Procedure GrandDecimal_Init()
  Protected i
  GDModeArrondi = #GDArrondiInferieur
  GDMultiExp(0) = 1
  For i = 1 To #GDNbreChiffres-1
    GDMultiExp(i) = GDMultiExp(i-1)*10
  Next
  GDdeQuad(-1, GDValeurSpecialeUnNegatif)
  For i = 0 To 10
    GDdeQuad(i, GDValeurSpeciale(i))
  Next
EndProcedure
GrandDecimal_Init()


; Réduit d'un certain nombre GrandDecimal sur "nGDDecimales" (arrondi ici) et normalisé (c'est à dire, pas de zéros au début et à la fin)
Procedure _GDNorm(*GD.GrandDecimal, nGDDecimales=#PB_Default)
  Protected count, eman, sman, i, stmax, exp, long, rup
  If (*GD\taille = 0)
    ; est 0, Infinity ou NaN
    ProcedureReturn 
  EndIf
  i = 0
  If (nGDDecimales >= 0)
    ; Ce nombre est réduit
    ; Toutes les parties inutiles de la mantisse à 0
    exp = *GD\exp - *GD\taille
    While ((exp+1)*#GDNbreChiffres < -nGDDecimales)
      *GD\man(i) = 0
      i + 1
      exp + 1
    Wend
    If (exp*#GDNbreChiffres < -nGDDecimales)
      ; Ignorer tous les points inutiles, à l'exception de la mantisse
      long = *GD\man(i) / GDMultiExp(#GDNbreChiffres-nGDDecimales% #GDNbreChiffres-1)
      ; Si rup = 1, alors il est arrondi
      Select GDModeArrondi
        Case #GDArrondiInferieur
        Case #GDArrondiSuperieur
          rup = 1
        Case #GDArrondiPlafond
          If (*GD\sgn > 0)
            rup = 1
          EndIf
        Case #GDArrondiPlancher
          If (*GD\sgn < 0)
            rup = 1
          EndIf
        Case #GDArrondiDemiInferieur, #GDArrondiDemiSuperieur
          If (Mod(long,10) > 5)
            rup = 1
          ElseIf (Mod(long,10) = 5)
            If (GDModeArrondi = #GDArrondiDemiSuperieur)
              rup = 1
            EndIf
          EndIf
      EndSelect
      If (Mod(nGDDecimales,#GDNbreChiffres) = 0)
        ; Cas particulier, si le corps qui est important pour l'arrondissement, la mantisse est la prochaine
        *GD\man(i) = 0
        i + 1
        If (i = *GD\taille)
          If (rup = 0)
            ClearStructure(*GD, GrandDecimal)
            *GD\exp = #GDExpNull
            ProcedureReturn 
          EndIf
          ; Pour l'arrondissement mis en place n'est pas une mantisse et doit être augmentée
          ReDim *GD\man(i)
          *GD\taille + 1
          *GD\exp + 1
        EndIf
        *GD\man(i) + rup
      Else
        ; Les nombres sans points supplémentaires seront écrits dans la mantisse (éventuellement arrondis)
        *GD\man(i) = (long/10 + rup) * GDMultiExp(#GDNbreChiffres-nGDDecimales%#GDNbreChiffres)
      EndIf
      If (rup = 1)
        ; Arrondir la mantisse si le nombre est trop grand
        While (*GD\man(i) = #GDLongueurMaxi)
          *GD\man(i) = 0
          i + 1
          If (i = *GD\taille)
            ; Pour l'arrondissement mis en place n'est pas une mantisse et doit être augmenté
            ReDim *GD\man(i)
            *GD\taille + 1
            *GD\exp + 1
          EndIf
          *GD\man(i) + 1
        Wend
      EndIf
    EndIf
  EndIf
  ; Si la mantisse finit par 0
  eman = i
  While (*GD\man(eman) = 0)
    eman + 1
    If (eman = *GD\taille)
      ; La mantisse entière est 0 -> le nombre est 0
      ClearStructure(*GD, GrandDecimal)
      *GD\exp = #GDExpNull
      ProcedureReturn 
    EndIf
  Wend
  ; Est égale à 0 au début de la mantisse
  sman = 0
  While (*GD\man(*GD\taille-sman-1) = 0)
    sman + 1
  Wend
  If (eman+sman > 0)
    ; La mantisse doit être réduite
    Protected Dim help.i(*GD\taille-eman-sman-1)
    For i = eman To *GD\taille-sman-1
      help(i-eman) = *GD\man(i)
    Next
    CopyArray(help(), *GD\man())
    *GD\taille = *GD\taille-eman-sman
    *GD\exp - sman
  EndIf
EndProcedure


; Copie un nombre GrandDecimal et stocke le résultat dans "*resultat" si le résultat est inexact en spécifiant 'nGDDecimales'
Procedure GDCopy(*GD.GrandDecimal, *resultat.GrandDecimal, nGDDecimales=#PB_Default)
  If (*GD <> *resultat)
    If (*GD\man() <> #Null)
      Dim *resultat\man(0)
    EndIf
    *resultat\exp  = *GD\exp
    *resultat\sgn  = *GD\sgn
    *resultat\taille = *GD\taille
    CopyArray(*GD\man(), *resultat\man())
    ;   CopyStructure(*GD, *resultat, GrandDecimal)
  EndIf
  If (nGDDecimales >= 0)
    _GDNorm(*resultat, nGDDecimales)
  EndIf
  ProcedureReturn *resultat
EndProcedure

; Inverse un nombre GrandDecimal et stocke le résultat dans "*résultats" si le résultat est inexact en déclarant «nGDDecimales'
Procedure GDNegative(*GD.GrandDecimal, *resultat.GrandDecimal, nGDDecimales=#PB_Default)
  GDCopy(*GD, *resultat, #PB_Default)
  *resultat\sgn * (-1)
  If (nGDDecimales >= 0)
    _GDNorm(*resultat, nGDDecimales)
  EndIf
  ProcedureReturn *resultat
EndProcedure


; Définit le mode comment arrondir
Procedure GDModeArrondi(mode)
  If (mode >= 0) And (mode <= #GDArrondiDemiSuperieur)
    GDModeArrondi = mode
  EndIf
EndProcedure


; Convertit une chaîne en un nombre GrandDecimal et stocke le résultat dans "*résultat"
Procedure GDdeString(str.s, *resultat.GrandDecimal)
  Protected *string.Character, pos, i, cntvman, cntnman, count
  ClearStructure(*resultat, GrandDecimal)
  *resultat\sgn = 1
  *string = @str
  If (PeekC(*string) = '-')
    ; Nombre est négatif
    *string + SizeOf(Character)
    *resultat\sgn = -1
  ElseIf (PeekC(*string) = '+')
    *string + SizeOf(Character)
  EndIf
  If (CompareMemoryString(*string, @"infinity", #PB_String_NoCase, 8) = #PB_String_Equal)
    ; Nombre est Infinity
    *resultat\exp = #GDExpInf
    ProcedureReturn *resultat
  ElseIf (CompareMemoryString(*string, @"nan", #PB_String_NoCase, 8) = #PB_String_Equal)
    *resultat\exp = #GDExpNaN
    ProcedureReturn *resultat
  EndIf
  str = PeekS(*string)
  *string = @str
  pos = FindString(str, ".", 0)
  If (pos = 0)
    pos = Len(str)+1
  EndIf
  ; Nombre de mantisse après / avant le point
  cntnman = Round((Len(str)-pos)/#GDNbreChiffres,1)
  cntvman = Round((pos-1)/#GDNbreChiffres,1)
  If (cntnman+cntvman <= 0)
    *resultat\sgn = 0
    *resultat\exp = #GDExpNull
    ProcedureReturn *resultat
  EndIf
  Dim *resultat\man(cntvman+cntnman-1)
  count = #GDNbreChiffres - (cntnman*#GDNbreChiffres-(Len(str)-pos))
  For i = 0 To cntnman-1
    ; Chiffres créés derrière le point de la mantisse
    *resultat\man(i) = Val(PeekS(*string+(pos+(cntnman-1-i)*#GDNbreChiffres)*SizeOf(Character), count)) * GDMultiExp(#GDNbreChiffres-count)
    count = #GDNbreChiffres
  Next
  pos - 1
  count = #GDNbreChiffres
  For i = cntnman To cntnman+cntvman-1
    ; Chiffres créés en face du point de la mantisse
    pos - #GDNbreChiffres
    If (pos < 0)
      count = #GDNbreChiffres+pos
      pos = 0
    EndIf
    *resultat\man(i) = Val(PeekS(*string+pos*SizeOf(Character), count))
  Next
  *resultat\taille = cntnman+cntvman
  *resultat\exp = cntvman
  _GDNorm(*resultat, #PB_Default)
  ProcedureReturn *resultat
EndProcedure


; Convertit un double en un nombre GrandDecimal et stocke le résultat dans '*resultat'
Procedure GDdeDouble(double.d, *resultat.GrandDecimal, nGDDecimales=#PB_Default)
  ClearStructure(*resultat, GrandDecimal)
  If IsNAN(double)
    *resultat\exp = #GDExpNaN
  ElseIf (double = 0)
    *resultat\sgn = 0
    *resultat\exp = #GDExpNull
  Else
    If (nGDDecimales < 0)
      nGDDecimales = 15*#GDNbreChiffres-1
    EndIf
    GDdeString(StrD(double, nGDDecimales+1), *resultat)
  EndIf
  _GDNorm(*resultat, nGDDecimales)
  ProcedureReturn *resultat
EndProcedure


; Convertit un Quad en un nombre GrandDecimal et stocke le résultat dans '*resultat'
Procedure GDdeQuad(quad.q, *resultat.GrandDecimal)
  ClearStructure(*resultat, GrandDecimal)
  If (quad < 0)
    quad * (-1)
    *resultat\sgn = -1
  Else
    *resultat\sgn = 1
  EndIf
  If (quad = 0)
    *resultat\sgn = 0
    *resultat\exp = #GDExpNull
    ProcedureReturn *resultat
  ElseIf (quad < #GDLongueurMaxi)
    Dim *resultat\man(0)
    *resultat\man(0) = quad
    *resultat\exp = 1
  ElseIf (quad < #GDLongueurMaxi*#GDLongueurMaxi)
    Dim *resultat\man(1)
    *resultat\man(0) = Mod(quad , #GDLongueurMaxi)
    *resultat\man(1) = quad / #GDLongueurMaxi
    *resultat\exp = 2
  Else
    Dim *resultat\man(2)
    *resultat\man(0) =  Mod(quad , #GDLongueurMaxi)
    *resultat\man(1) = (quad / #GDLongueurMaxi % #GDLongueurMaxi)
    *resultat\man(2) =  quad / #GDLongueurMaxi  / #GDLongueurMaxi
    *resultat\exp = 3
  EndIf
  *resultat\taille = *resultat\exp
  _GDNorm(*resultat, #PB_Default)
  ProcedureReturn *resultat
EndProcedure


; Convertit un nombre GrandDecimal en chaîne
Procedure.s GDStr(*GD.GrandDecimal, nGDDecimales=#PB_Default)
  Protected str.s
  Protected i, cntdig
  If (nGDDecimales >= 0)
    GDCopy(*GD, *GD, nGDDecimales)
  EndIf
  If (*GD\sgn = -1)
    str = "-"
    ;   ElseIf (*GD\sgn = 1)
    ;     str = "+"
  EndIf
  If (*GD\taille = 0)
    ;valeurs spéciales
    Select *GD\exp
      Case #GDExpNaN
        ProcedureReturn "NaN"
      Case #GDExpInf
        ProcedureReturn str+"Infinity"
    EndSelect
  EndIf
  cntdig = -1
  If (*GD\exp <= 0)
    ; Nombre est inférieur à 0
    If (nGDDecimales = 0)
      ProcedureReturn str+"0"
    EndIf
    cntdig = -*GD\exp*#GDNbreChiffres
    str + "0."
    If (cntdig <> 0)
      ; Écrit des zéros qui ne sont pas stockées dans la mantisse
      str + RSet("", cntdig, "0")
    EndIf
  EndIf
  i = *GD\taille
  While (#True)
    i - 1
    If (nGDDecimales >= 0) And (cntdig >= nGDDecimales)
      ; Trop de chiffres dans la chaîne -> la chaîne sera tronquée
      str = PeekS(@str, Len(str)-(cntdig-nGDDecimales))
      Break
    EndIf
    If (cntdig = -1)
      If (*GD\taille-i-1 = *GD\exp)
        str + "."
        cntdig = #GDNbreChiffres
      EndIf
    Else
      cntdig + #GDNbreChiffres
    EndIf
    If (i >= 0)
      ; Écrit le numéro de la mantisse (éventuellement avec des zéros comme préfixe)
      If (i = *GD\taille-1) And (*GD\exp > 0)
        str + Str(*GD\man(i))
      Else
        str + RSet(Str(*GD\man(i)), #GDNbreChiffres, "0")
      EndIf
    Else
      ; La mantisse est passé à travers
      If (nGDDecimales < 0) And (cntdig <> -1)
        ; Si 'nGDDecimales' est manquant, nous sommes prêts
        Break
      EndIf
      str + RSet("", #GDNbreChiffres, "0")
    EndIf
  Wend
  ProcedureReturn str
EndProcedure


; Compare deux nombres GrandDecimal
; -1: *GDa < *GDb, 0: *GDa = *GDb, 1: *GDa > *GDb
Procedure GDCompare(*GDa.GrandDecimal, *GDb.GrandDecimal)
  If ((*GDa\taille = 0) And (*GDa\exp = #GDExpNaN)) Or ((*GDb\taille = 0) And (*GDb\exp = #GDExpNaN))
    ; Si il y a un certain nombre de 'NaN', le résultat est 0
    ProcedureReturn 0
  EndIf
  ; Comparer Signe
  If (*GDa\sgn < *GDb\sgn)
    ProcedureReturn -1
  ElseIf (*GDa\sgn > *GDb\sgn)
    ProcedureReturn 1
  ElseIf (*GDa\sgn = 0)
    ; Les deux nombres sont égaux à 0
    ProcedureReturn 0
  EndIf
  ; Comparer à l'infini
  If (*GDa\taille = 0) And (*GDa\exp = #GDExpInf)
    If (*GDb\taille = 0) And (*GDb\exp = #GDExpInf)
      ProcedureReturn 0
    EndIf
    ProcedureReturn 1 * *GDa\sgn
  ElseIf (*GDb\taille = 0) And (*GDb\exp = #GDExpInf)
    ProcedureReturn (-1) * *GDa\sgn
  EndIf
  ; Comparaison de deux nombres normaux
  Protected ia, ib, cmp
  cmp = *GDa\exp - *GDb\exp
  ; Comparaison des exposants
  If (cmp < 0)
    ProcedureReturn (-1) * *GDa\sgn
  ElseIf (cmp > 0)
    ProcedureReturn 1 * *GDa\sgn
  EndIf
  ia = *GDa\taille
  ib = *GDb\taille
  Repeat
    ia - 1
    ib - 1
    If (ia < 0) And (ib < 0)
      ; Les deux chiffres sont pareils
      Break
    EndIf
    ; Un certain nombre d'extrémités, l'autre nombre est plus grand (pour +) ou moins (pour -)
    If (ia < 0)
      ProcedureReturn (-1) * *GDa\sgn
    ElseIf (ib < 0)
      ProcedureReturn 1 * *GDa\sgn
    EndIf
    ; Comparer la Mantisse
    cmp = *GDa\man(ia) - *GDb\man(ib)
    If (cmp < 0)
      ProcedureReturn (-1) * *GDa\sgn
    ElseIf (cmp > 0)
      ProcedureReturn 1 * *GDa\sgn
    EndIf
  ForEver
  ProcedureReturn 0
EndProcedure

Procedure GDAbs(*GDa.GrandDecimal)
  *GDa\Sgn=#GDPositif
EndProcedure

; Ajouter deux nombres GrandDecimal et stocke le résultat dans '*resultat'
Procedure GDAdd(*GDa.GrandDecimal, *GDb.GrandDecimal, *resultat.GrandDecimal, nGDDecimales=#PB_Default)
  If ((*GDa\taille = 0) And (*GDa\exp = #GDExpNaN)) Or ((*GDb\taille = 0) And (*GDb\exp = #GDExpNaN))
    ; Un nombre est 'NaN'
    ClearStructure(*resultat, GrandDecimal)
    *resultat\exp = #GDExpNaN
    ProcedureReturn *resultat
  ElseIf (*GDa\taille = 0) And (*GDa\exp = #GDExpNull)
    ; '*GDa' est 0, le résultat est '*GDb'
    ProcedureReturn GDCopy(*GDb, *resultat, nGDDecimales)
  ElseIf (*GDb\taille = 0) And (*GDb\exp = #GDExpNull)
    ; '*GDb' est 0, le résultat est '*GDa'
    ProcedureReturn GDCopy(*GDa, *resultat, nGDDecimales)
  EndIf
  Protected sub.GrandDecimal
  ; Deux différents Signe -> il est soustrait
  If (*GDb\sgn = -1) And (*GDa\sgn = 1)
    GDNegative(*GDb, sub, #PB_Default)
    ProcedureReturn GDSub(*GDa, sub, *resultat, nGDDecimales)
  ElseIf (*GDa\sgn = -1) And (*GDb\sgn = 1)
    GDNegative(*GDa, sub, #PB_Default)
    ProcedureReturn GDSub(*GDb, sub, *resultat, nGDDecimales)
  EndIf
  ; Adition avec Infinity
  If (*GDa\taille = 0) And (*GDa\exp = #GDExpInf)
    GDCopy(*GDa, *resultat, nGDDecimales)
    ProcedureReturn *resultat
  ElseIf (*GDb\taille = 0) And (*GDb\exp = #GDExpInf)
    GDCopy(*GDb, *resultat, nGDDecimales)
    ProcedureReturn *resultat
  EndIf
  ; Addition de deux nombres normaux
  Protected sman, eman, i, ia, ib, longa, longb, ub, sgn
  sgn = *GDa\sgn
  ; Recherche dans les plus grands exposants
  sman = *GDa\exp
  If (sman < *GDb\exp)
    sman = *GDb\exp
  EndIf
  ; Trouver le plus petit exposant (ou limiter 'nGDDecimales')
  If (nGDDecimales < 0)
    eman = *GDa\exp - *GDa\taille
    If (eman > *GDb\exp - *GDb\taille)
      eman = *GDb\exp - *GDb\taille
    EndIf
  Else
    eman = -Round((nGDDecimales+1)/#GDNbreChiffres, 1)
  EndIf
  Protected Dim help.i(sman-eman)
  i = eman
  ub = 0
  While (i < sman)
    ; Ajouter deux mantisses
    longa = 0
    longb = 0
    ia = i + *GDa\taille - *GDa\exp
    ib = i + *GDb\taille - *GDb\exp
    If (ia < 0)
    ElseIf (ia < *GDa\taille)
      longa = *GDa\man(ia)
    EndIf
    If (ib < 0)
    ElseIf (ib < *GDb\taille)
      longb = *GDb\man(ib)
    EndIf
    help(i-eman) = (longa+longb+ub) % #GDLongueurMaxi
    ; Transfert de l'addition
    ub = (longa+longb+ub) / #GDLongueurMaxi
    i + 1
  Wend
  ; Enregistrer le dernier transfert
  help(sman-eman) = ub
  ClearStructure(*resultat, GrandDecimal)
  Dim *resultat\man(sman-eman)
  CopyArray(help(), *resultat\man())
  *resultat\exp = sman+1
  *resultat\sgn = sgn
  *resultat\taille = sman-eman+1
  _GDNorm(*resultat, nGDDecimales)
  ProcedureReturn *resultat
EndProcedure


; Soustrait deux nombres GrandDecimal et stocke le résultat dans '*resultat'
Procedure GDSub(*GDa.GrandDecimal, *GDb.GrandDecimal, *resultat.GrandDecimal, nGDDecimales=#PB_Default)
  If ((*GDa\taille = 0) And (*GDa\exp = #GDExpNaN)) Or ((*GDb\taille = 0) And (*GDb\exp = #GDExpNaN))
    ; Un nombre est 'NaN'
    ClearStructure(*resultat, GrandDecimal)
    *resultat\exp = #GDExpNaN
    ProcedureReturn *resultat
  EndIf
  Protected add.GrandDecimal
  If (*GDa\sgn * *GDb\sgn < 1)
    ; Les nombres ont des signes différents, ou un nombre est 0
    GDNegative(*GDb, add, #PB_Default)
    ProcedureReturn GDAdd(*GDa, add, *resultat, nGDDecimales)
  EndIf
  ; Soustraction avec Infinity
  If (*GDa\taille = 0) And (*GDa\exp = #GDExpInf)
    If (*GDb\taille = 0) And (*GDb\exp = #GDExpInf)
      ; Infinity-Infinity = NaN
      ClearStructure(*resultat, GrandDecimal)
      *resultat\exp = #GDExpNaN
      ProcedureReturn *resultat
    EndIf
    GDCopy(*GDa, *resultat, nGDDecimales)
    ProcedureReturn *resultat
  ElseIf (*GDb\taille = 0) And (*GDb\exp = #GDExpInf)
    GDNegative(*GDb, *resultat, nGDDecimales)
    ProcedureReturn *resultat
  EndIf
  ; Soustraction avec nombres normaux
  Protected cmp, sman, eman, i, ia, ib, longa, longb, long, ub
  ; 'cmp' est le signe du nouveau nombre
  cmp = GDCompare(*GDa, *GDb)
  If (cmp = 0)
    ClearStructure(*resultat, GrandDecimal)
    *resultat\exp = #GDExpNull
    ProcedureReturn *resultat
  ElseIf (cmp * *GDa\sgn < 0)
    ; Permuter les chiffres si |*GDa|<|*GDb|
    Swap *GDa, *GDb
  EndIf
  sman = *GDa\exp
  ; Trouver le plus petit exposant (ou limiter 'nGDDecimales')
  If (nGDDecimales < 0)
    eman = *GDa\exp - *GDa\taille
    If (eman > *GDb\exp - *GDb\taille)
      eman = *GDb\exp - *GDb\taille
    EndIf
  Else
    eman = -Round((nGDDecimales+1)/#GDNbreChiffres, 1)
  EndIf
  Protected Dim help.i(sman-eman-1)
  i = eman
  ub = 0
  While (i < sman)
    ; Soustraire deux mantisse
    longa = 0
    longb = 0
    ia = i + *GDa\taille - *GDa\exp
    ib = i + *GDb\taille - *GDb\exp
    If (ia < 0)
    ElseIf (ia < *GDa\taille)
      longa = *GDa\man(ia)
    EndIf
    If (ib < 0)
    ElseIf (ib < *GDb\taille)
      longb = *GDb\man(ib)
    EndIf
    long = longa-longb-ub
    If (long < 0)
      ; Premier nombre est inférieur au deuxième -> Transférer
      long + #GDLongueurMaxi
      ub = 1
    EndIf
    help(i-eman) = long
    i + 1
  Wend
  ClearStructure(*resultat, GrandDecimal)
  Dim *resultat\man(sman-eman-1)
  CopyArray(help(), *resultat\man())
  *resultat\exp = sman
  *resultat\sgn = cmp
  *resultat\taille = sman-eman
  _GDNorm(*resultat, nGDDecimales)
  ProcedureReturn *resultat
EndProcedure


; Multiplie deux nombres GrandDecimal et stocke le résultat dans '*resultat'
Procedure GDMul(*GDa.GrandDecimal, *GDb.GrandDecimal, *resultat.GrandDecimal, nGDDecimales=#PB_Default)
  If ((*GDa\taille = 0) And (*GDa\exp = #GDExpNaN)) Or ((*GDb\taille = 0) And (*GDb\exp = #GDExpNaN))
    ; Un nombre est 'NaN'
    ClearStructure(*resultat, GrandDecimal)
    *resultat\exp = #GDExpNaN
    ProcedureReturn *resultat
  EndIf
  Protected sgn
  sgn = *GDa\sgn * *GDb\sgn
  If ((*GDa\taille = 0) And (*GDa\exp = #GDExpInf)) Or ((*GDb\taille = 0) And (*GDb\exp = #GDExpInf))
    ; Multiplication avec Infinity
    ClearStructure(*resultat, GrandDecimal)
    *resultat\sgn = sgn
    If (*resultat\sgn = 0)
      ; 0*Infinity = NaN
      *resultat\exp = #GDExpNaN
    Else
      *resultat\exp = #GDExpInf
    EndIf
    ProcedureReturn *resultat
  EndIf
  ; Multiplication avec nombres normaux
  Protected taille, exp, stman, i, k, rsi, ub, quad.q
  If (sgn = 0)
    ClearStructure(*resultat, GrandDecimal)
    *resultat\exp = #GDExpNull
    ProcedureReturn *resultat
  EndIf
  stman = 0
  ; Nouvel Exposant et longueur de la mantisse
  exp  = *GDa\exp  + *GDb\exp
  taille = *GDa\taille + *GDb\taille
  If (nGDDecimales >= 0)
    ; Si 'nGDDecimales' est spécifié, les parties arrières ne sont pas calculées
    i = Round((nGDDecimales+2)/#GDNbreChiffres, 1)
    If (taille > i+exp)
      stman = taille-(i+exp)
      taille = i+exp
    EndIf
  EndIf
  If (taille <= 0)
    ClearStructure(*resultat, GrandDecimal)
    *resultat\exp = #GDExpNull
    ProcedureReturn *resultat
  EndIf
  Protected Dim help.i(taille-1)
  For i = 0 To *GDa\taille-1
    ; Aller premier nombre
    ub = 0
    For k = 0 To *GDb\taille-1
      ; Aller au deuxième nombre
      rsi = i+k-stman
      If (rsi >= 0)
        ; Multiplier les deux mantisses, Ajoutez pour le transfert précédent et mettre l'ancienne valeur dans le résultat
        If (i > 0)
          quad = *GDa\man(i) * *GDb\man(k) + ub + help(rsi)
        Else
          quad = *GDa\man(i) * *GDb\man(k) + ub
        EndIf
        help(rsi) = quad % #GDLongueurMaxi
        ub = quad / #GDLongueurMaxi
      EndIf
    Next
    rsi = i+*GDb\taille-stman
    ; Enregistrer le dernier transfert
    If (rsi >= 0)
      help(rsi) + ub
    EndIf
  Next
  ClearStructure(*resultat, GrandDecimal)
  Dim *resultat\man(taille-1)
  CopyArray(help(), *resultat\man())
  *resultat\exp = exp
  *resultat\sgn = sgn
  *resultat\taille = taille
  _GDNorm(*resultat, nGDDecimales)
  ProcedureReturn *resultat
EndProcedure


;Divise deux nombres GrandDecimal et stocke le résultat dans '*resultat'
Procedure GDDiv(*GDa.GrandDecimal, *GDb.GrandDecimal, *resultat.GrandDecimal, nGDDecimales=#PB_Default)
  If ((*GDa\taille = 0) And (*GDa\exp = #GDExpNaN)) Or ((*GDb\taille = 0) And (*GDb\exp = #GDExpNaN))
    ; Un nombre est 'NaN'
    ClearStructure(*resultat, GrandDecimal)
    *resultat\exp = #GDExpNaN
    ProcedureReturn *resultat
  EndIf
  Protected sgn
  sgn = *GDa\sgn * *GDb\sgn
  If (*GDa\taille = 0) And (*GDa\exp = #GDExpInf)
    If (*GDb\taille = 0) And (*GDb\exp = #GDExpInf)
      ; Infinity/Infinity = NaN
      ClearStructure(*resultat, GrandDecimal)
      *resultat\exp = #GDExpNaN
      ProcedureReturn *resultat
    EndIf
    If (sgn = 0)
      sgn = *GDa\sgn
    EndIf
    ClearStructure(*resultat, GrandDecimal)
    *resultat\exp = #GDExpInf
    *resultat\sgn = sgn
    ProcedureReturn *resultat
  ElseIf (*GDb\taille = 0) And (*GDb\exp = #GDExpInf)
    ClearStructure(*resultat, GrandDecimal)
    *resultat\exp = #GDExpNull
    ProcedureReturn *resultat
  EndIf
  If (*GDb\taille = 0) And (*GDb\exp = #GDExpNull)
    ; Division par 0
    ClearStructure(*resultat, GrandDecimal)
    *resultat\exp = #GDExpNaN
    ProcedureReturn *resultat
  ElseIf (*GDa\taille = 0) And (*GDa\exp = #GDExpNull)
    ; Diviseur est 0
    ClearStructure(*resultat, GrandDecimal)
    *resultat\exp = #GDExpNull
    ProcedureReturn *resultat
  EndIf
  Protected taille, exp, i, ia, k, ka, ataille
  Protected diva.q, quad.q, quadb.q, ub, qhat, qrem, double.d
  ; Nouvel Exposant et longueur de la Mantisse
  If (nGDDecimales < 0)
    nGDDecimales = ((*GDa\taille-*GDa\exp) + (*GDb\taille-*GDb\exp) + 1) * #GDNbreChiffres
  EndIf
  exp  = *GDa\exp  - *GDb\exp + 1
  taille = exp+Round((nGDDecimales+2)/#GDNbreChiffres, 1)
  If (taille <= 0)
    ClearStructure(*resultat, GrandDecimal)
    *resultat\exp = #GDExpNull
    ProcedureReturn *resultat
  EndIf
  ; Dividende nécessite nouvelle longueur
  ataille = taille + *GDb\taille
  If (ataille <= *GDa\taille)
    ataille = *GDa\taille+1
  EndIf
  Dim help(taille-1)
  Protected Dim diva.i(ataille-1)
  Protected Dim divb.i(*GDb\taille-1)
  ; Normaliser diviseur (La mantisse ne peut d'abord pas commencer par 0)
  k = 0
  qhat = *GDb\man(*GDb\taille-1)
  Repeat
    qhat / 10
    k + 1
  Until (qhat = 0)
  ; Stocker dividende (normalisé ici)
  ub = 0
  ia = ataille-*GDa\taille-1
  For i = 0 To *GDa\taille-1
    quad = *GDa\man(i) * GDMultiExp(#GDNbreChiffres-k)
    diva(ia) = quad % #GDLongueurMaxi + ub
    ub = quad / #GDLongueurMaxi
    ia + 1
  Next
  diva(ia) = ub
  ; Stocker diviseur (normalisé ici)
  ub = 0
  For i = 0 To *GDb\taille-1
    quad = *GDb\man(i) * GDMultiExp(#GDNbreChiffres-k)
    divb(i) = quad % #GDLongueurMaxi + ub
    ub = quad / #GDLongueurMaxi
  Next
  ; Démarrer le calcul
  ia = ataille-1
  For i = taille-1 To 0 Step -1
    If (ia > 0)
      diva = diva(ia) * #GDLongueurMaxi + diva(ia-1)
    Else
      diva = diva(ia) * #GDLongueurMaxi
    EndIf
    qhat = diva / divb(*GDb\taille-1)
    qrem = diva % divb(*GDb\taille-1)
    If (*GDb\taille >= 2)
      ; Diviseur mantisse a plus d'un résultat correct de la division
      If (ia >= 2)
        quad = qrem * #GDLongueurMaxi + diva(ia-2)
      Else
        quad = qrem * #GDLongueurMaxi
      EndIf
      quadb = divb(*GDb\taille-2) * qhat
      If (quad < quadb)
        qhat - 1
      EndIf
    EndIf
    If (qhat > 0)
      ; Soustraire 'qhat*Divisor' de dividende
      ka = ia-*GDb\taille
      ub = 0
      For k = 0 To *GDb\taille-1
        quad = diva(ka) - divb(k) * qhat - ub
        If (quad < 0)
          double = Round((-quad) / #GDLongueurMaxi, 1)
          ub = double
          quad + ub * #GDLongueurMaxi
        Else
          ub = 0
        EndIf
        diva(ka) = quad
        ka + 1
      Next
      If (ub > diva(ka))
        ; Résultat correct de la division encore, il est sorti quand la soustraction d'un nombre négatif
        diva(ka) - ub
        Repeat
          qhat - 1
          ; Ajouter le diviseur au dividende à nouveau
          ka = ia-*GDb\taille
          ub = 0
          For k = 0 To *GDb\taille-1
            diva(ka) + divb(k) + ub
            If (diva(ka) >= #GDLongueurMaxi)
              diva(ka) - #GDLongueurMaxi
              ub = 1
            Else: ub = 0
            EndIf
            ka + 1
          Next
          diva(ka) + ub
        Until (diva(ka) >= 0)
      EndIf
      ; Enregistrer le résultat de la division
      diva(ka) = 0
      help(i) = qhat
    EndIf
    ia - 1
  Next
  ClearStructure(*resultat, GrandDecimal)
  Dim *resultat\man(taille-1)
  CopyArray(help(), *resultat\man())
  *resultat\exp = exp
  *resultat\sgn = sgn
  *resultat\taille = taille
  _GDNorm(*resultat, nGDDecimales)
  ProcedureReturn *resultat
EndProcedure


; Calcule le résultat de la fonction exponentielle et les stocke dans '*resultat'
Procedure GDExp(*GD.GrandDecimal, *resultat.GrandDecimal, nGDDecimales)
  Protected.GrandDecimal num, den, sum, GDi, div
  Protected i
  If (*GD\taille = 0)
    Select *GD\exp
      Case #GDExpNaN
        GDCopy(*GD, *resultat)
      Case #GDExpInf
        If (*GD\sgn = 1)
          ; e^inf = inf
          GDCopy(*GD, *resultat)
        Else
          ; e^(-inf) = 0
          ClearStructure(*resultat, GrandDecimal)
          *resultat\exp = #GDExpNull
        EndIf
      Case #GDExpNull
        ; e^0 = 1
        GDCopy(GDValeurSpeciale(1), *resultat)
    EndSelect
    ProcedureReturn *resultat
  EndIf
  If (*GD\sgn < 0)
    ; e^(-a) = 1/e^a
    GDNegative(*GD, num)
    GDExp(num, den, nGDDecimales)
    GDDiv(GDValeurSpeciale(1), den, *resultat, nGDDecimales)
    ProcedureReturn *resultat
  EndIf
  ; e^z = somme(z^k/k!, k=0..infinity)
  GDCopy(*GD, num)
  GDCopy(GDValeurSpeciale(1), den)
  GDCopy(GDValeurSpeciale(1), sum)
  i = 1
  Repeat
    GDDiv(num, den, div, nGDDecimales)
    If (div\taille = 0) And (div\exp = #GDExpNull)
      ; Les termes de la somme sont trop petits
      Break
    EndIf
    GDAdd(sum, div, sum)
    i + 1
    GDMul(num, *GD, num)
    GDdeQuad(i, GDi)
    GDMul(den, GDi, den)
  ForEver
  ProcedureReturn GDCopy(sum, *resultat, nGDDecimales)
EndProcedure


; Calcule le résultat de la fonction logarithmique et le stocke dans '*resultat'
Procedure GDLog(*GD.GrandDecimal, *resultat.GrandDecimal, nGDDecimales) ; Calcule le logarithme d'un nombre
  Protected.GrandDecimal num, den, qnum, qden, div, mul, sum, sumb, GDi
  Protected long, multi, i, ub, GDtaille, cmp
  If ((*GD\taille = 0) And (*GD\exp = #GDExpNaN)) Or (*GD\sgn < 0)
    ; Nombre est NaN ou négatif
    ClearStructure(*resultat, GrandDecimal)
    *resultat\exp = #GDExpNaN
    ProcedureReturn *resultat
  EndIf
  If (*GD\taille = 0)
    Select *GD\exp
      Case #GDExpInf
        ; ln(inf) = inf
        GDCopy(*GD, *resultat)
      Case #GDExpNull
        ; log(0) = -inf
        ClearStructure(*resultat, GrandDecimal)
        *resultat\exp = #GDExpInf
        *resultat\sgn = -1
    EndSelect
    ProcedureReturn *resultat
  EndIf
  If (GDCompare(*GD, GDValeurSpeciale(10)) > 0)
    ; Si le nombre est supérieur à 10
    ; log(a) = log(a/10^multi) + log(10)*multi
    long = *GD\man(*GD\taille-1) / 10
    While (long <> 0)
      multi + 1
      long / 10
    Wend
    GDtaille = *GD\taille
    Dim num\man(GDtaille)
    num\taille = GDtaille+1
    num\exp = 1
    num\sgn = 1
    For i = GDtaille-1 To 0 Step -1
      If (multi = 0)
        num\man(i+1) = *GD\man(i)
      Else
        num\man(i+1) = *GD\man(i) / GDMultiExp(multi) + ub
        ub = (*GD\man(i) % GDMultiExp(multi)) * GDMultiExp(#GDNbreChiffres-multi)
      EndIf
    Next
    num\man(0) = ub
    _GDNorm(num)
    GDLog(num, sum, nGDDecimales)
    multi + (*GD\exp-1) * #GDNbreChiffres
    GDdeQuad(multi, mul)
    GDLog(GDValeurSpeciale(10), sumb, nGDDecimales+multi/2)
    GDMul(mul, sumb, sumb)
    GDAdd(sum, sumb, *resultat, nGDDecimales)
    ProcedureReturn *resultat
  ElseIf (GDCompare(*GD, GDValeurSpeciale(2)) > 0)
    ; Si le nombre est supérieur à 2
    ; log(a) = log(a/2^multi) + log(2)*multi
    long = *GD\man(*GD\taille-1)
    If (long >= 8)
      GDDiv(*GD, GDValeurSpeciale(8), num, nGDDecimales)
      GDLog(num, sum, nGDDecimales)
      GDLog(GDValeurSpeciale(2), sumb, nGDDecimales)
      GDMul(GDValeurSpeciale(3), sumb, sumb)
    ElseIf (long >= 4)
      GDDiv(*GD, GDValeurSpeciale(4), num, nGDDecimales)
      GDLog(num, sum, nGDDecimales)
      GDLog(GDValeurSpeciale(2), sumb, nGDDecimales)
      GDMul(GDValeurSpeciale(2), sumb, sumb)
    Else
      GDDiv(*GD, GDValeurSpeciale(2), num, nGDDecimales)
      GDLog(num, sum, nGDDecimales)
      GDLog(GDValeurSpeciale(2), sumb, nGDDecimales)
    EndIf
    GDAdd(sum, sumb, *resultat, nGDDecimales)
    ProcedureReturn *resultat
  EndIf
  cmp = GDCompare(*GD, GDValeurSpeciale(1))
  If (cmp > 0)
    ; Si le nombre est supérieur à 1
    ; log(a) = sum((2/(2*k-1))*((a-1)/(a+1))^(2*i-1), i=1..infinity)
    GDCopy(GDValeurSpeciale(0), sum)
    GDSub(*GD, GDValeurSpeciale(1), num)
    GDAdd(*GD, GDValeurSpeciale(1), den)
    GDMul(num, num, qnum)
    GDMul(den, den, qden)
    GDMul(num, GDValeurSpeciale(2), num)
    i = 1
    Repeat
      GDdeQuad(i*2-1, GDi)
      GDDiv(num, den, div, nGDDecimales)
      GDDiv(div, GDi, div, nGDDecimales)
      If (div\taille = 0) And (div\exp = #GDExpNull)
        ; Les termes de la somme sont trop petits
        Break
      EndIf
      GDAdd(sum, div, sum)
      i + 1
      GDMul(num, qnum, num)
      GDMul(den, qden, den)
    ForEver
    ProcedureReturn GDCopy(sum, *resultat, nGDDecimales)
  ElseIf (cmp = 0)
    ; log(1) = 0
    GDCopy(GDValeurSpeciale(0), *resultat)
    ProcedureReturn *resultat
  Else
    ; Si le nombre est inférieur à 1
    ; log(a) = -log(1/a)
    GDDiv(GDValeurSpeciale(1), *GD, div, nGDDecimales)
    GDLog(div, num, nGDDecimales)
    GDNegative(num, *resultat, nGDDecimales)
    ProcedureReturn *resultat
  EndIf
EndProcedure



CompilerIf #PB_Compiler_Processor = #PB_Processor_x86  
  
  Global a.NGF, b.NGF, Resultat.NGF, GDa.GrandDecimal, GDb.GrandDecimal, Resultat2.GrandDecimal, Resultat3.GrandDecimal
  
  Procedure.s AjouterChaine(Argument1.s, Argument2.s, decimales.i=0)
    GDdeString(Argument1, GDa)
    GDdeString(Argument2, GDb)
    GDAdd(GDa, GDb, Resultat2)
    ProcedureReturn GDstr(Resultat2, decimales)
  EndProcedure
  
  Procedure.s SoustraireChaine(Argument1.s, Argument2.s, decimales.i=0)
    GDdeString(Argument1, GDa)
    GDdeString(Argument2, GDb)
    GDSub(GDa, GDb, Resultat2)
    ProcedureReturn GDstr(Resultat2, decimales)
  EndProcedure
  
  Procedure.s MultiplierChaine(Argument1.s, Argument2.s, decimales.i=0)
    GDdeString(Argument1, GDa)
    GDdeString(Argument2, GDb)
    GDMul(GDa, GDb, Resultat2)
    ProcedureReturn GDstr(Resultat2, decimales)
  EndProcedure
  
  Procedure.s DiviserChaine(Argument1.s, Argument2.s, decimales.i=0)
    GDdeString(Argument1, GDa)
    GDdeString(Argument2, GDb)
    GDDiv(GDa, GDb, Resultat2, decimales)
    ProcedureReturn GDstr(Resultat2, decimales)
  EndProcedure
  
  Procedure.s PuissanceChaine(Nombre$, Exposant.s) ; Calcule la puissance d'un nombre
                                                   ;Procedure.s PuissanceChaine(Argument1.s, Argument2.s, decimales.i=0)
                                                   ;  GDdeString(Argument1, GDa)
    GDdeString(Exposant, b)
    
    ;  For i = 1 To Val(Argument2)
    ;    GDMul(GDb, GDb, Resultat) ; c = a * b
    ;    GDCopy(Resultat, Resultat2) ;b = a
    ;  Next  
    ChaineVersNbre(@Nombre$, a)
    NGFPuissance(a, b, Resultat)
    ProcedureReturn GDStr(Resultat) ; GD
  EndProcedure
  
  Procedure.s CarreChaine(Argument$, Decimales.i=#Decimales_Defaut) ; Calcule le carré d'un nombre
    GDdeString(Argument$, a)
    GDMul(a, a, Resultat2)
    ProcedureReturn GDstr(Resultat2, decimales)
  EndProcedure
  
  Procedure.s Remise(PrixHT$, PrixPaye$, Decimales.i=#Decimales_Defaut) ; Calculer un pourcentage de remise
    Protected PrixCoutant.GrandDecimal, Total.GrandDecimal, GDc.GrandDecimal
    GDdeString(PrixHT$, GDa)
    GDdeString(PrixPaye$, GDb)
    GDdeString("100", GDc)
    
    GDSub(GDa, GDb, PrixCoutant) ; Prix coûtant = Prix Ht - Prix payé	
    GDDiv(PrixCoutant, Gda,Total); Total = Prix Coutant / Prix Ht
    GDMul(Total, Gdc, Resultat2) ;  Total = Prix coûtant * GDc
    
    ProcedureReturn GDstr(Resultat2, decimales)
  EndProcedure
  
  Procedure.s Pourcentage(Argument1$, Argument2$, decimales.i=#Decimales_Defaut, Mode.i=0)
    Protected Retour.GrandDecimal, GDc.GrandDecimal
    GDdeString(Argument1$, GDa)
    GDdeString(Argument2$, GDb)
    GDdeString("100", GDc)
    If mode = 0
      GDDiv(GDa, GDc, Retour) ; Retour = GDa/GDc
      GDMul(GDb, Retour, Resultat2) ;Resultat2 = Retour * GDb
    Else
      GDDiv(GDc, GDb, Retour) ; Retour = GDc/GDb
      GDMul(GDa, Retour, Resultat2) ;Resultat2 = GDa * Retour
    EndIf
    ProcedureReturn GDstr(Resultat2, decimales)
  EndProcedure
  
  Procedure.s PourcentageAugmentation ( Argument1$, Argument2$, Decimales.i=#Decimales_Defaut)
    Protected Retour.GrandDecimal, Sortie.GrandDecimal, GDc.GrandDecimal
    GDdeString(Argument1$, GDa)
    GDdeString(Argument2$, GDb)
    GDdeString("100", GDc)
    
    GDDiv(GDa, Gdc, Retour) ; Retour = GDa / GDc
    GDMul(GDb, Retour, Sortie) ;Sortie = Retour * GDb
    GDAdd(GDa, Sortie, Resultat2) ; Resultat2 = GDa + Sortie
    
    ProcedureReturn GDstr(Resultat2, decimales)
  EndProcedure
  
  Procedure.s PourcentageDiminution (Argument1$, Argument2$, Decimales.i=#Decimales_Defaut)
    Protected Retour.GrandDecimal, Sortie.GrandDecimal, GDc.GrandDecimal
    GDdeString(Argument1$, GDa)
    GDdeString(Argument2$, GDb)
    GDdeString("100", GDc)
    
    GDDiv(GDa, Gdc, Retour) ; Retour = GDa / GDc
    GDMul(GDb, Retour, Sortie) ;Sortie = Retour * GDb
    GDSub(GDa, Sortie, Resultat2) ; Resultat2 = GDa - Sortie
    
    ProcedureReturn GDstr(Resultat2, decimales)
  EndProcedure
  
  Procedure.f Racine_N(Nbre.d, Racine.i, Decimales.i=#Decimales_Defaut) ; Calcule la racine n ème d'un nombre
    Protected Dim Temporaire.d(1) 
    Temporaire(0)=Nbre: Temporaire(1)=Nbre/Racine
    While Abs(Temporaire(1)-Temporaire(0))>Decimales
      Temporaire(0)=Temporaire(1)
      Temporaire(1)=((Racine-1.0)*Temporaire(1)+Nbre/Pow(Temporaire(1),Racine-1.0))/Racine
    Wend
    ProcedureReturn Temporaire(1)
  EndProcedure
  
  CompilerIf #PB_Compiler_IsMainFile	
    ;/ Test Fonctions de chaînes mathématiques
    InitSprite()
    InitKeyboard()
    InitMouse()
    
    Enumeration
      ;Fenetres
      #Fenetre_principale
      ;Actions
      #Sortie
      #Aucune
      ;Autres
    EndEnumeration
    
    Global Police =FontID(LoadFont(#PB_Any, "Arial Rounded MT", 16, #PB_Font_Bold))
    Global Police2 =FontID(LoadFont(#PB_Any, "Brush Script MT", 20, #PB_Font_Italic))
    Global Police3 =FontID(LoadFont(#PB_Any, "computerfont", 20, #PB_Font_Bold))
    
    ExamineDesktops() : Global  Largeur_Ecran = DesktopWidth(0) , Hauteur_Ecran = DesktopHeight(0) , Profondeur = DesktopDepth(0)
    Global x, y, z, Texte.s, Titre.s = "Test Nombre Grand Format"
    Largeur_Ecran-5 : Hauteur_Ecran-28 
    
    ; ouvrir une fenêtre maximisée de la même taille que le bureau et sans bordure
    ;
    Global h_Fenetre = OpenWindow(#Fenetre_principale, 0, 0, Largeur_Ecran, Hauteur_Ecran, Titre, #PB_Window_TitleBar)
    ;
    ; ouvrir un écran de la même taille que la fenêtre
    ;
    OpenWindowedScreen(h_Fenetre, 0, 0, Largeur_Ecran, Hauteur_Ecran, 0, 0, 0, #PB_Screen_SmartSynchronization)
    ClearScreen($50AA50)
    StartDrawing(ScreenOutput())
    ;}
    ;- début de l'affichage
    DrawingFont(Police)
    DrawingMode(#PB_2DDrawing_AlphaChannel)
    
    
    X = 0 : Y = 0
    BackColor(Point(0,0))
    ShowCursor_(1)
    
    ;- Ajouter
    DrawText(X, Y, "AjouterChaine",$FFFF) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "    1524654654685468651656465468") : Y + TextHeight(" ")
    DrawText(X, Y, "+") : Y + TextHeight(" ")
    DrawText(X, Y, "546413524164316513652146132516") : Y + TextHeight(" ")
    DrawText(X, Y, "------------------------------------------------------") : Y + TextHeight(" ")
    DrawText(X, Y, AjouterChaine("1524654654685468651656465468", "546413524164316513652146132516")) : Y + TextHeight(Chr(32))
    ;- Soustraire
    DrawText(X, Y, "SoustraireChaine", $FFFF) : Y + TextHeight(Chr(32))
    DrawText(X, Y, " 546413524164316513652146132516") : Y + TextHeight(" ")
    DrawText(X, Y, "-") : Y + TextHeight(" ")
    DrawText(X, Y, "     1524654654685468651656465468") : Y + TextHeight(" ")
    DrawText(X, Y, "------------------------------------------------------") : Y + TextHeight(" ")
    DrawText(X, Y, SoustraireChaine("546413524164316513652146132516", "1524654654685468651656465468")) : Y + TextHeight(Chr(32))
    ;- Multiplier
    DrawText(X, Y, "MultiplierChaine", $FFFF) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "     1524654654685468651656465468") : Y + TextHeight(" ")
    DrawText(X, Y, "*") : Y + TextHeight(" ")
    DrawText(X, Y, " 546413524164316513652146132516") : Y + TextHeight(" ")
    DrawText(X, Y, "------------------------------------------------------") : Y + TextHeight(" ")
    DrawText(X, Y, MultiplierChaine("1524654654685468651656465468", "546413524164316513652146132516")) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "65536*256 = "+MultiplierChaine("65536", "256")) : Y + TextHeight(Chr(32))
    ;- Diviser
    DrawText(X, Y, "DiviserChaine", $FFFF) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "     1524654654685468651656465468") : Y + TextHeight(" ")
    DrawText(X, Y, "/") : Y + TextHeight(" ")
    DrawText(X, Y, "                                       54641352416") : Y + TextHeight(" ")
    DrawText(X, Y, "------------------------------------------------------") : Y + TextHeight(" ")
    DrawText(X, Y, "                           "+DiviserChaine("1524654654685468651656465468", "54641352416")) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "10/3 = "+DiviserChaine("10","3",145)) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "42/2.5 = "+DiviserChaine("42", "2.5",2)) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "1 / 7  =  "+DiviserChaine("1", "7",144)) : Y + TextHeight(" ")
    ;- Puissance
    ;DrawText(X, Y, "PuissanceChaine",$FFFF) : Y + TextHeight(Chr(32))
    ;DrawText(X, Y, "24^2 = " + PuissanceChaine("2","24")) : Y + TextHeight(Chr(32))
    ;DrawText(X, Y, "50^50 = " + PuissanceChaine("50","50")) : Y + TextHeight(Chr(32))
    ;DrawText(X, Y, "99^99 = " + PuissanceChaine("99","99")) : Y + TextHeight(Chr(32))
    ;- Racine
    DrawText(X, Y, "Racine",$FFFF) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "racine 125ème de 5642 = "+StrD(Pow(5642, 1/125),8)) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "Première estimation:",$C0FF) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "Racine_N(5642, 125) = " + StrD(Racine_N(5642,125))) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "Et la meilleure:",$C0FF) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "Racine_N(5642,125,0.00001) = "+StrD(Racine_N(5642,125,0.00001))) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "Racine carrée de 2 = "+StrD( Racine_N(2,2,#Decimales_Defaut),9)) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "Racine carrée de 3 = "+StrD( Racine_N(3,2))) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "Racine cubique de 27 = "+StrD( Racine_N(27,3),0)) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "Racine 8ème de 4 = "+StrD(Racine_N(4,8))) : Y + TextHeight(Chr(32))
    ;- Remise
    DrawText(X, Y, "Remise",$FFFF) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "1 article coûte 148 euros, que j'ai payé 136,16 euros" + ", ma ristourne est de : "+Remise("148","136.16",2)+" %") : Y + TextHeight(Chr(32))
    DrawText(X, Y, "1 article à 136,16 euros, je l'ai payé 133,44 euros" + ", on m'a fait une remise de : "+Remise("136.16","133.436",2)+" %") : Y + TextHeight(Chr(32))
    X = Largeur_Ecran / 2 : Y = 0
    ;- Augmentation
    DrawText(X, Y, "Augmentation",$FFFF) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "1370 + 5.31% = " + PourcentageAugmentation("1370","5.31",2)) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "136,16 + 2% = " + PourcentageAugmentation("136.16","2",2)) : Y + TextHeight(Chr(32))
    ;- Diminution
    DrawText(X, Y, "Diminution", $FFFF) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "2300 - 20% = " + PourcentageDiminution("2300","20")) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "1840 - 2% = " + PourcentageDiminution("1840","2",2)) : Y + TextHeight(Chr(32))
    ;-Equivalence
    DrawText(X, Y, "Equivalences",$FFFF) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "1% de 1234 est = à " + Pourcentage("1234","1",2)) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "12,34 est 1% de "+ Pourcentage("246.8","20",0,1)) : Y + TextHeight(Chr(32))
    
    DrawText(X, Y, "20% de 1234 est = à " + Pourcentage("1234", "20",2)) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "246,80 est 20% de " + Pourcentage("246.8","20",0, 1)) : Y + TextHeight(Chr(32))
    ;- Carré
    DrawText(X, Y, "CarreChaine",$FFFF) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "Carré de 4294967296 = "+CarreChaine("4294967296")) : Y + TextHeight(Chr(32))
    Y + TextHeight(Chr(32))
    Y + TextHeight(Chr(32))
    DrawText(X, Y, "Carré de 1.999999 = "+CarreChaine("1.999999",6)) : Y + TextHeight(Chr(32))
    DrawText(X, Y, "Carré de 2 = "+CarreChaine("2")) : Y + TextHeight(Chr(32))
    
    
    ;- fin d'affichage
    DrawingFont(Police2)
    Texte = "Pour quitter, pressez une touche ou cliquez la souris"
    DrawText((Largeur_Ecran-TextWidth(Texte)) / 2, Hauteur_Ecran - 30, Texte, $FFFF)
    StopDrawing()
    ;- gestion des événements en boucle sans fin
    Global action.i = #Aucune
    Repeat
      Global Evenement = WindowEvent()
      Select Evenement
        Case #PB_Event_CloseWindow
          action = #Sortie
        Case 0
          ;
          ; il n'y a pas d'événement, donc faisons nos trucs graphiques
          ExamineKeyboard()
          If KeyboardPushed(#PB_Key_All)
            action = #Sortie
          EndIf
          ExamineMouse()
          If MouseButton(#PB_MouseButton_Left) <> 0 
            action = #Sortie
          EndIf
          If MouseButton(#PB_MouseButton_Middle) <> 0 
            action = #Sortie
          EndIf
          If MouseButton(#PB_MouseButton_Right) <> 0 
            action = #Sortie
          EndIf
          ;
          ; et montrons les choses sur l'écran
          ;
          FlipBuffers()
      EndSelect
    Until action = #Sortie
    ;- fermeture de l'écran & de la fenêtre en douceur
    CloseScreen()
    CloseWindow(#Fenetre_principale)
    ;}
  CompilerEndIf	
CompilerElse
  MessageRequester("Attention", "Vous devez être en mode x86"+#CRLF$+"Ce logiciel ne fonctionne pas en 64 bits", #MB_ICONINFORMATION)
  End
CompilerEndIf
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Frenchy Pilou
Messages : 2194
Inscription : jeu. 27/janv./2005 19:07

Re: Nombres Grand Format (x86)

Message par Frenchy Pilou »

Grand comment le nombre? Combien de chiffres maxi (avec ses décimales ou sans) ? :)
Est beau ce qui plaît sans concept :)
Speedy Galerie
Avatar de l’utilisateur
SPH
Messages : 4722
Inscription : mer. 09/nov./2005 9:53

Re: Nombres Grand Format (x86)

Message par SPH »

Moi, il y a quelques annees, je calculais des chiffres de 660 000 chiffres.

Mais avant tout, j'ai les memes questions que frenchy pilou :?:
http://HexaScrabble.com/
!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.00 - 64 bits
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Nombres Grand Format (x86)

Message par Micoute »

Bonjour à tous les deux, en fait, c'est une question pertinente, car c'est un calcul basé sur les strings qui n'ont pas vraiment de limite, mais on peut aussi les transformer en nombre. J'ai d'ailleurs mis un autotest !
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
MLD
Messages : 1097
Inscription : jeu. 05/févr./2009 17:58
Localisation : Bretagne

Re: Nombres Grand Format (x86)

Message par MLD »

SPH a écit Moi, il y a quelques annees, je calculais des chiffres de 660 000 chiffres.
Certainement l'argent qu'il avait sur son compte en banque.
@ Micoute
quand tu traduit en chiffre le maxi dépasse t'il le double précision?
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Nombres Grand Format (x86)

Message par Micoute »

Bonjour aussi à toi MLD.

Pour répondre à ta question, je répond : oui, bien sûr !
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Répondre