Voilà le code issu du module decimal servant à additionner deux décimaux.
J'ai commenté les différentes parties en surbrillance. Je précise que c'est en python3.
def__add__(self,other,context=None):"""Returns self + other. -INF + INF (or the reverse) cause InvalidOperation errors. """other=_convert_other(other)ifotherisNotImplemented:returnotherifcontextisNone:context=getcontext()ifself._is_specialorother._is_special:ans=self._check_nans(other,context)ifans:returnansifself._isinfinity():# If both INF, same sign => same as both, opposite => error.ifself._sign!=other._signandother._isinfinity():returncontext._raise_error(InvalidOperation,'-INF + INF')returnDecimal(self)ifother._isinfinity():returnDecimal(other)# Can't both be infinity hereexp=min(self._exp,other._exp)negativezero=0ifcontext.rounding==ROUND_FLOORandself._sign!=other._sign:# If the answer is 0, the sign should be negative, in this case.negativezero=1def__add__(self,other,context=None):"""Returns self + other. -INF + INF (or the reverse) cause InvalidOperation errors. """other=_convert_other(other)ifotherisNotImplemented:returnotherifcontextisNone:context=getcontext()ifself._is_specialorother._is_special:ans=self._check_nans(other,context)ifans:returnansifself._isinfinity():# If both INF, same sign => same as both, opposite => error.ifself._sign!=other._signandother._isinfinity():returncontext._raise_error(InvalidOperation,'-INF + INF')returnDecimal(self)ifother._isinfinity():returnDecimal(other)# Can't both be infinity hereexp=min(self._exp,other._exp)negativezero=0ifcontext.rounding==ROUND_FLOORandself._sign!=other._sign:# If the answer is 0, the sign should be negative, in this case.negativezero=1ifnotselfandnotother:sign=min(self._sign,other._sign)ifnegativezero:sign=1ans=_dec_from_triple(sign,'0',exp)ans=ans._fix(context)returnansifnotself:exp=max(exp,other._exp-context.prec-1)ans=other._rescale(exp,context.rounding)ans=ans._fix(context)returnansifnotother:exp=max(exp,self._exp-context.prec-1)ans=self._rescale(exp,context.rounding)ans=ans._fix(context)returnansop1=_WorkRep(self)op2=_WorkRep(other)op1,op2=_normalize(op1,op2,context.prec)result=_WorkRep()ifop1.sign!=op2.sign:# Equal and oppositeifop1.int==op2.int:ans=_dec_from_triple(negativezero,'0',exp)ans=ans._fix(context)returnansifop1.int<op2.int:op1,op2=op2,op1# OK, now abs(op1) > abs(op2)ifop1.sign==1:result.sign=1op1.sign,op2.sign=op2.sign,op1.signelse:result.sign=0# So we know the sign, and op1 > 0.elifop1.sign==1:result.sign=1op1.sign,op2.sign=(0,0)else:result.sign=0# Now, op1 > abs(op2) > 0//'A ce stade, on n a toujours pas commencé à additionner. Combien ont coûté toutes ces opérations ????'ifop2.sign==0:#' Ca y est, ils se mettent à additionner les numérateurs !!'result.int=op1.int+op2.intelse:result.int=op1.int-op2.int//oulessoustrairesuivantlessignes//'Et c est reparti pour renormaliser le tout !!!'result.exp=op1.expans=Decimal(result)ans=ans._fix(context)returnansifnotselfandnotother:sign=min(self._sign,other._sign)ifnegativezero:sign=1ans=_dec_from_triple(sign,'0',exp)ans=ans._fix(context)returnansifnotself:exp=max(exp,other._exp-context.prec-1)ans=other._rescale(exp,context.rounding)ans=ans._fix(context)returnansifnotother:exp=max(exp,self._exp-context.prec-1)ans=self._rescale(exp,context.rounding)ans=ans._fix(context)returnansop1=_WorkRep(self)op2=_WorkRep(other)op1,op2=_normalize(op1,op2,context.prec)result=_WorkRep()ifop1.sign!=op2.sign:# Equal and oppositeifop1.int==op2.int:ans=_dec_from_triple(negativezero,'0',exp)ans=ans._fix(context)returnansifop1.int<op2.int:op1,op2=op2,op1# OK, now abs(op1) > abs(op2)ifop1.sign==1:result.sign=1op1.sign,op2.sign=op2.sign,op1.signelse:result.sign=0# So we know the sign, and op1 > 0.elifop1.sign==1:result.sign=1op1.sign,op2.sign=(0,0)else:result.sign=0# Now, op1 > abs(op2) > 0ifop2.sign==0:result.int=op1.int+op2.intelse:result.int=op1.int-op2.intresult.exp=op1.expans=Decimal(result)ans=ans._fix(context)returnans
En version float: c'est une seule ligne de code directement envoyée à la FPU et qui prend deux cycles d'horloge (impossible de faire moins).
Rien que les 10 premières lignes de test de ce module prennent 10 fois plus d'opérations élémentaires.
Donc si ton module decimal prend le même temps qu'avec les floats c'est que ton module est bogué et qu'il est resté en float tout le temps.
[^] # Re: Petit résumé et tests dans la réalité
Posté par snowball (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 2.
Voilà le code issu du module decimal servant à additionner deux décimaux.
J'ai commenté les différentes parties en surbrillance. Je précise que c'est en python3.
En version float: c'est une seule ligne de code directement envoyée à la FPU et qui prend deux cycles d'horloge (impossible de faire moins).
Rien que les 10 premières lignes de test de ce module prennent 10 fois plus d'opérations élémentaires.
Donc si ton module decimal prend le même temps qu'avec les floats c'est que ton module est bogué et qu'il est resté en float tout le temps.