Page 1 sur 2

Tronque(nombre flottant)

Publié : ven. 06/avr./2018 9:33
par Zorro
Je ne sais plus si ça a deja été fait ...


voici une petite procedure qui recupere la partie decimal d'un nombre
par exemple le nombre flottant "155.256457899"
ça renvoi "256457899"

le contraire de INT() :)

Code : Tout sélectionner


floating.d =  8.788999557

Procedure Tronque(floating.d )
		;G-Rom
		integer.i = Abs(Int(floating))
		decimal.d = (Abs(floating) - integer) * 1000000000
		final.i = decimal
		ProcedureReturn final.i
EndProcedure

Debug " 8.788999557"
Debug  Tronque(floating.d)

en theorie on pourrai le faire avec un MOD(nombre,1)
mais ça ne renvoie pas la meme chose chez moi ... peut etre une histoire d'arrondis

Re: Tronque(nombre flottant)

Publié : ven. 06/avr./2018 16:19
par G-Rom

Code : Tout sélectionner

floating.d = 15.256457899
integer.i = Int(floating)
decimal.d = floating - integer

Debug integer
Debug decimal

Re: Tronque(nombre flottant)

Publié : ven. 06/avr./2018 17:19
par Ar-S
G-Rom : il récupère la partie de droite après la virgile en fait, x.yyyy sans le x.

Zorro : note qu'avec 888.7889995575 ça chie aussi

En fusionnant les 2

Code : Tout sélectionner




Procedure Tronque(number.d)
integer.i = Int(number)
decimal.d = number - integer
String.s=StringField(StrD(decimal),2,".")

ProcedureReturn Val(String)
EndProcedure


Debug tronque(15.256457899)
Debug tronque(888.7889995575)

Re: Tronque(nombre flottant)

Publié : ven. 06/avr./2018 17:38
par G-Rom
j'avais compris, une simple multiplication suffit :

Code : Tout sélectionner

floating.d = 15.256457899
integer.i = Abs(Int(floating))
decimal.d = (Abs(floating) - integer) * 1000000000
final.i = decimal


Debug integer
Debug final
Ca doit surement déconner avec des arrondis sur d'autres nombre.
faut surement jouer avec les bit pour avoir un resultat plus proche certainement , mais c'est une piste ;)

Re: Tronque(nombre flottant)

Publié : ven. 06/avr./2018 20:29
par Zorro
ça marche pas mal

j'adopte !

Re: Tronque(nombre flottant)

Publié : lun. 09/avr./2018 11:47
par nico
une variante qui trouve le multiplicateur:

Code : Tout sélectionner

floating.d = 158758.285214789
integer.i = Abs(Int(floating))
decimal.d = (Abs(floating) - integer) * Pow(10, Len(StrD((Abs(floating) - integer)))-2)
final.i = decimal


Debug integer
Debug final

Re: Tronque(nombre flottant)

Publié : mar. 10/avr./2018 21:29
par zaphod_b
Salut,
sans passer par les string (curieux de savoir si ca marche avec tous les procs) :

Code : Tout sélectionner

Procedure nb_deci(n.d) ;nombre de décimales
  Protected f.d,i
  For i=1 To 15
    f=n*Pow(10,i) 
    If f-IntQ(f)=0
      Break
    EndIf   
  Next 
  ProcedureReturn i
EndProcedure


n.d=888.7889995575  ;45.10100002
d=nb_deci(n)
Debug "décimales :"+d
CompilerIf #PB_Compiler_Processor=#PB_Processor_x64     
  f=Mod(n*Pow(10,d),Pow(10,d)) 
CompilerElse
  f.q=(n-Int(n))*Pow(10,d)  
CompilerEndIf

Debug "résultat :"+f

Code corrigé, qui fonctionne en x86 et x64.

Re: Tronque(nombre flottant)

Publié : mar. 10/avr./2018 21:50
par Zorro
chez moi renvoi (I7)
-2147483648

Re: Tronque(nombre flottant)

Publié : mer. 11/avr./2018 4:45
par zaphod_b
oups, ca marchait en x64 et pas en x86...
j'ai corrigé et ca devrait le faire.
merci d'avoir testé.

Re: Tronque(nombre flottant)

Publié : mer. 11/avr./2018 9:37
par Zorro
ha oui , tres fort ! :)

les gars , le zaphod_b c'est pas un manchot :)

j'adopte .... ce serai bien que Fred ajoute cette fonction a Purebasic
on ne s'en sert pas tout les jours, mais ça peut etre utile quelques fois :)

Re: Tronque(nombre flottant)

Publié : mer. 11/avr./2018 9:57
par GallyHC
Bonjour,

Je ne sais pas si cela est une erreur ou moi qui fait fausse route. mais si je mets "888.7800", comme valeur, je devrais avoir en résultat 7800 et pas 78 (qui ne sont pas les mêmes choses non?). Il ne faudrait pas confondre 0.0078 et 0.7800, je penses ?

Code : Tout sélectionner

Procedure nb_deci(n.d) ;nombre de décimales
  Protected f.d,i
  For i=1 To 15
    f=n*Pow(10,i) 
    If f-IntQ(f)=0
      Break
    EndIf   
  Next 
  ProcedureReturn i
EndProcedure


n.d=888.7800  ;45.10100002
d=nb_deci(n)
Debug "décimales :"+d
CompilerIf #PB_Compiler_Processor=#PB_Processor_x64     
  f=Mod(n*Pow(10,d),Pow(10,d)) 
CompilerElse
  f.q=(n-Int(n))*Pow(10,d)  
CompilerEndIf

Debug "résultat :"+f
Cordialement,
GallyHC

Re: Tronque(nombre flottant)

Publié : mer. 11/avr./2018 11:41
par Kwai chang caine
Bah mathématiquement parlant les derniers zéros après la virgule sont aussi utile que ceux avant la partie entière :wink:
Essaie sur une calculatrice elle va te virer tout ça vite fait

Code : Tout sélectionner

000888.7800 = 888.78

Re: Tronque(nombre flottant)

Publié : mer. 11/avr./2018 16:51
par Zorro
oui 0.7800 ou 0.78 c'est pareil ! :)

Re: Tronque(nombre flottant)

Publié : mer. 11/avr./2018 18:20
par GallyHC
Moi aussi va falloir que je me repose. ^^

Re: Tronque(nombre flottant)

Publié : jeu. 12/avr./2018 9:27
par PAPIPP
Bonjour à tous

Le format *.d est le format ayant la plus grande amplitude en option de base des processeurs X86

±2.2250738585072013e-308 à ±1.7976931348623157e+308, 15 Chiffres significatifs

Voici un test des principales options je fais varier vd.d de #pi * 10^-10 à #pi*10^10 on est loin de l’amplitude offerte par le format *.d

Pour être cohérent en 32 et 64 bits avec le format *.d il suffit d’utiliser le format *.q et intq valq.q=intd(val.d) pour la partie entière

Et voici le prg de test. A vous de juger des résultats.

Code : Tout sélectionner

; Procedure.S formf(val.D,sig=0)
;   If val<0
;     sign$=""
;     expo10.l=Int(Log10(val*(-1)))+1
;   Else
;     sign$="+"
;     expo10.l=Int(Log10(val))+1
;   EndIf
;   ms.d=val/Pow(10,expo10)
;   If sig=0
;     ProcedureReturn StrD(ms,18)+"E"+Str(Expo10)
;   Else
;     ProcedureReturn sign$+StrD(ms,18)+"E"+Str(Expo10)
;   EndIf
; EndProcedure
; Procedure.s Float_64_bits_Valu(D.D,SIG=0)
;   M.d
;   E.w
;   !fninit                 ;Or Not ;-)
;   !fld qword[p.v_D]         ;Load Value
;   !fxtract                ;Extract Value in Mantissa (st0) and Exponent (st1)
;   !fstp qword[p.v_M]        ;Mantissa
;   !fistp word [p.v_E]            ;Exponent
;   ;   val.d=m*Pow(2,E)
;   mant$=formf(m)
;   expo$=Str(e)
;   ProcedureReturn mant$+"*"+expo$
; EndProcedure

; procedure.d G_rom1(vd.d)
;   integer.q = Intq(Vd)
;   final.d=VD-integer
;  ProcedureReturn  final
; endprocedure 
procedure.d G_rom1(vd.d)
  integer.i = Int(Vd)
  final.d=VD-integer
 ProcedureReturn  final
endprocedure 
procedure.d G_rom2(vd.d)
  integer.q = Intq(Vd)
  final.d=VD-integer
 ProcedureReturn  final
endprocedure 
Procedure.q G_rom3(vd.d)
integer.Q = Abs(Intq(VD))
decimal.d = (Abs(vd) - integer) * 1000000000
final.q = decimal
 ProcedureReturn  final
endprocedure 
Procedure.q zaphod(n.d) ;nombre de décimales
  Protected f.d,i,fin.q
  For i=1 To 15
    f=n*Pow(10,i)
    If f-IntQ(f)=0
      Break
    EndIf   
  Next
  fin.q=(n-Intq(n))*Pow(10,i)  
  ProcedureReturn fin
EndProcedure

for i=-10 to 10
  Vd.d=#pi*pow(10,i)
  ;   debug _n(i)+_d(vd,18)+"  "+formf(vd)+"  "+Float_64_bits_Valu(vd)
  debug "Valeur flot ="+strd(vd,18) ;; avec 18 décimales
   debug "G-rom1="+strd(G_rom2(vd),18)
  debug "G-rom="+G_rom3(vd)
  debug "Zaphod="+zaphod(vd)
next  

A+