-- | A simple implementation of floating point numbers with a selectable-- precision. The number of digits in the mantissa is selected by the-- 'Epsilon' type class from the "Fixed" module.---- The numbers are stored in base 10.moduleData.Number.BigFloat(BigFloat,Epsilon,Eps1,EpsDiv10,Prec10,Prec50,PrecPlus20,)whereimportNumeric(showSigned)importData.Number.FixedimportqualifiedData.Number.FixedFunctionsasFbase::(Numa)=>abase=10-- This representation is stupid, two Integers makes more sense,-- but is more work.-- | Floating point number where the precision is determined by the type /e/.dataBigFloate=BF(Fixede)Integerderiving(Eq,Ord)instance(Epsilone)=>Show(BigFloate)whereshowsPrec=showSignedshowBF-- Assumes base is 10whereshowBF(BFme)=showsPrec0m.showString"e".showsPrec0einstance(Epsilone)=>Num(BigFloate)whereBFm1e1+BFm2e2=bf(m1'+m2')ewhere(m1',m2')=ife==e1then(m1,m2/base^(e-e2))else(m1/base^(e-e1),m2)e=e1`max`e2-- Do - via negateBFm1e1*BFm2e2=bf(m1*m2)(e1+e2)negate(BFme)=BF(-m)eabs(BFme)=BF(absm)esignum(BFm_)=bf(signumm)0fromIntegeri=bf(fromIntegeri)0instance(Epsilone)=>Real(BigFloate)wheretoRational(BFem)=toRationale*base^^minstance(Epsilone)=>Fractional(BigFloate)whererecip(BFme)=bf(base/m)(-(e+1))-- Take care not to lose precision for small numbersfromRationalx=ifabsx<1thenrecip$bf(fromRational(recipx))0elsebf(fromRationalx)0-- normalizing constructor-- XXX The scaling is very inefficientbf::(Epsilone)=>Fixede->Integer->BigFloatebfme|m==0=BF00|m<0=-bf(-m)e|m>=base=bf(m/base)(e+1)|m<1=bf(m*base)(e-1)|otherwise=BFmeinstance(Epsilone)=>RealFrac(BigFloate)whereproperFractionx@(BFme)=ife<0then(0,x)elselet(i,f)=properFraction(m*base^^e)in(i,bff0)instance(Epsilone)=>Floating(BigFloate)wherepi=bfpi0sqrt=toFloat1F.sqrtexp=toFloat1F.explog=toFloat1F.logsin=toFloat1F.sincos=toFloat1F.costan=toFloat1F.tanasin=toFloat1F.asinacos=toFloat1F.acosatan=toFloat1F.atansinh=toFloat1F.sinhcosh=toFloat1F.coshtanh=toFloat1F.tanhasinh=toFloat1F.asinhacosh=toFloat1F.acoshatanh=toFloat1F.atanhinstance(Epsilone)=>RealFloat(BigFloate)wherefloatRadix_=basefloatDigits(BFm_)=floor$logBasebase$recip$fromRational$precisionmfloatRange_=(minBound,maxBound)decodeFloatx@(BFme)=letd=floatDigitsxin(round$m*base^d,fromIntegere-d)encodeFloatme=bf(fromIntegerm)(toIntegere)exponent(BF_e)=fromIntegeresignificand(BFm_)=BFm0scaleFloatn(BFme)=BFm(e+toIntegern)isNaN_=FalseisInfinite_=FalseisDenormalized_=FalseisNegativeZero_=FalseisIEEE_=FalsetoFloat1::(Epsilone)=>(Rational->Rational->Rational)->BigFloate->BigFloatetoFloat1fx@(BFme)=fromRational$f(precisionm*scl)(toRationalm*scl)wherescl=base^^e