Movatterモバイル変換


[0]ホーム

URL:


{-# LANGUAGE Trustworthy #-}{-# LANGUAGE ScopedTypeVariables #-}------------------------------------------------------------------------------- |-- Module      :  Data.Fixed-- Copyright   :  (c) Ashley Yakeley 2005, 2006, 2009-- License     :  BSD-style (see the file libraries/base/LICENSE)---- Maintainer  :  Ashley Yakeley <ashley@semantic.org>-- Stability   :  experimental-- Portability :  portable---- This module defines a \"Fixed\" type for fixed-precision arithmetic.-- The parameter to Fixed is any type that's an instance of HasResolution.-- HasResolution has a single method that gives the resolution of the Fixed type.---- This module also contains generalisations of div, mod, and divmod to work-- with any Real instance.-------------------------------------------------------------------------------moduleData.Fixed(div',mod',divMod',Fixed(..),HasResolution(..),showFixed,E0,Uni,E1,Deci,E2,Centi,E3,Milli,E6,Micro,E9,Nano,E12,Pico)whereimportData.DataimportGHC.ReadimportText.ParserCombinators.ReadPrecimportText.Read.Lexdefault()-- avoid any defaulting shenanigans-- | generalisation of 'div' to any instance of Realdiv'::(Reala,Integralb)=>a->a->bdiv'nd=floor((toRationaln)/(toRationald))-- | generalisation of 'divMod' to any instance of RealdivMod'::(Reala,Integralb)=>a->a->(b,a)divMod'nd=(f,n-(fromIntegralf)*d)wheref=div'nd-- | generalisation of 'mod' to any instance of Realmod'::(Reala)=>a->a->amod'nd=n-(fromIntegerf)*dwheref=div'nd-- | The type parameter should be an instance of 'HasResolution'.newtypeFixeda=MkFixedIntegerderiving(Eq-- ^ @since 2.01,Ord-- ^ @since 2.01)-- We do this because the automatically derived Data instance requires (Data a) context.-- Our manual instance has the more general (Typeable a) context.tyFixed::DataTypetyFixed=mkDataType"Data.Fixed.Fixed"[conMkFixed]conMkFixed::ConstrconMkFixed=mkConstrtyFixed"MkFixed"[]Prefix-- | @since 4.1.0.0instance(Typeablea)=>Data(Fixeda)wheregfoldlkz(MkFixeda)=k(zMkFixed)agunfoldkz_=k(zMkFixed)dataTypeOf_=tyFixedtoConstr_=conMkFixedclassHasResolutionawhereresolution::pa->IntegerwithType::(pa->fa)->fawithTypefoo=fooundefinedwithResolution::(HasResolutiona)=>(Integer->fa)->fawithResolutionfoo=withType(foo.resolution)-- | @since 2.01instanceEnum(Fixeda)wheresucc(MkFixeda)=MkFixed(succa)pred(MkFixeda)=MkFixed(preda)toEnum=MkFixed.toEnumfromEnum(MkFixeda)=fromEnumaenumFrom(MkFixeda)=fmapMkFixed(enumFroma)enumFromThen(MkFixeda)(MkFixedb)=fmapMkFixed(enumFromThenab)enumFromTo(MkFixeda)(MkFixedb)=fmapMkFixed(enumFromToab)enumFromThenTo(MkFixeda)(MkFixedb)(MkFixedc)=fmapMkFixed(enumFromThenToabc)-- | @since 2.01instance(HasResolutiona)=>Num(Fixeda)where(MkFixeda)+(MkFixedb)=MkFixed(a+b)(MkFixeda)-(MkFixedb)=MkFixed(a-b)fa@(MkFixeda)*(MkFixedb)=MkFixed(div(a*b)(resolutionfa))negate(MkFixeda)=MkFixed(negatea)abs(MkFixeda)=MkFixed(absa)signum(MkFixeda)=fromInteger(signuma)fromIntegeri=withResolution(\res->MkFixed(i*res))-- | @since 2.01instance(HasResolutiona)=>Real(Fixeda)wheretoRationalfa@(MkFixeda)=(toRationala)/(toRational(resolutionfa))-- | @since 2.01instance(HasResolutiona)=>Fractional(Fixeda)wherefa@(MkFixeda)/(MkFixedb)=MkFixed(div(a*(resolutionfa))b)recipfa@(MkFixeda)=MkFixed(div(res*res)a)whereres=resolutionfafromRationalr=withResolution(\res->MkFixed(floor(r*(toRationalres))))-- | @since 2.01instance(HasResolutiona)=>RealFrac(Fixeda)whereproperFractiona=(i,a-(fromIntegrali))wherei=truncateatruncatef=truncate(toRationalf)roundf=round(toRationalf)ceilingf=ceiling(toRationalf)floorf=floor(toRationalf)chopZeros::Integer->StringchopZeros0=""chopZerosa|moda10==0=chopZeros(diva10)chopZerosa=showa-- only works for positive ashowIntegerZeros::Bool->Int->Integer->StringshowIntegerZerosTrue_0=""showIntegerZeroschopTrailingZerosdigitsa=replicate(digits-lengths)'0'++s'wheres=showas'=ifchopTrailingZerosthenchopZerosaelseswithDot::String->StringwithDot""=""withDots='.':s-- | First arg is whether to chop off trailing zerosshowFixed::(HasResolutiona)=>Bool->Fixeda->StringshowFixedchopTrailingZerosfa@(MkFixeda)|a<0="-"++(showFixedchopTrailingZeros(asTypeOf(MkFixed(negatea))fa))showFixedchopTrailingZerosfa@(MkFixeda)=(showi)++(withDot(showIntegerZeroschopTrailingZerosdigitsfracNum))whereres=resolutionfa(i,d)=divModares-- enough digits to be unambiguousdigits=ceiling(logBase10(fromIntegerres)::Double)maxnum=10^digits-- read floors, so show must ceil for `read . show = id` to hold. See #9240fracNum=divCeil(d*maxnum)resdivCeilxy=(x+y-1)`div`y-- | @since 2.01instance(HasResolutiona)=>Show(Fixeda)whereshow=showFixedFalse-- | @since 4.3.0.0instance(HasResolutiona)=>Read(Fixeda)wherereadPrec=readNumberconvertFixedreadListPrec=readListPrecDefaultreadList=readListDefaultconvertFixed::foralla.HasResolutiona=>Lexeme->ReadPrec(Fixeda)convertFixed(Numbern)|Just(i,f)<-numberToFixeden=return(fromIntegeri+(fromIntegerf/(10^e)))wherer=resolution(undefined::Fixeda)-- round 'e' up to help make the 'read . show == id' property-- possible also for cases where 'resolution' is not a-- power-of-10, such as e.g. when 'resolution = 128'e=ceiling(logBase10(fromIntegerr)::Double)convertFixed_=pfaildataE0-- | @since 4.1.0.0instanceHasResolutionE0whereresolution_=1-- | resolution of 1, this works the same as IntegertypeUni=FixedE0dataE1-- | @since 4.1.0.0instanceHasResolutionE1whereresolution_=10-- | resolution of 10^-1 = .1typeDeci=FixedE1dataE2-- | @since 4.1.0.0instanceHasResolutionE2whereresolution_=100-- | resolution of 10^-2 = .01, useful for many monetary currenciestypeCenti=FixedE2dataE3-- | @since 4.1.0.0instanceHasResolutionE3whereresolution_=1000-- | resolution of 10^-3 = .001typeMilli=FixedE3dataE6-- | @since 2.01instanceHasResolutionE6whereresolution_=1000000-- | resolution of 10^-6 = .000001typeMicro=FixedE6dataE9-- | @since 4.1.0.0instanceHasResolutionE9whereresolution_=1000000000-- | resolution of 10^-9 = .000000001typeNano=FixedE9dataE12-- | @since 2.01instanceHasResolutionE12whereresolution_=1000000000000-- | resolution of 10^-12 = .000000000001typePico=FixedE12

[8]ページ先頭

©2009-2025 Movatter.jp