Movatterモバイル変換


[0]ホーム

URL:


{-# LANGUAGE Trustworthy #-}{-# LANGUAGE NoImplicitPrelude, MagicHash #-}------------------------------------------------------------------------------- |-- Module      :  Numeric-- Copyright   :  (c) The University of Glasgow 2002-- License     :  BSD-style (see the file libraries/base/LICENSE)---- Maintainer  :  libraries@haskell.org-- Stability   :  provisional-- Portability :  portable---- Odds and ends, mostly functions for reading and showing-- 'RealFloat'-like kind of values.-------------------------------------------------------------------------------moduleNumeric(-- * ShowingshowSigned,showIntAtBase,showInt,showHex,showOct,showEFloat,showFFloat,showGFloat,showFFloatAlt,showGFloatAlt,showFloat,showHFloat,floatToDigits,-- * Reading-- | /NB:/ 'readInt' is the \'dual\' of 'showIntAtBase',-- and 'readDec' is the \`dual\' of 'showInt'.-- The inconsistent naming is a historical accident.readSigned,readInt,readDec,readOct,readHex,readFloat,lexDigits,-- * MiscellaneousfromRat,Floating(..))whereimportGHC.BaseimportGHC.ReadimportGHC.RealimportGHC.FloatimportGHC.NumimportGHC.ShowimportText.ParserCombinators.ReadP(ReadP,readP_to_S,pfail)importqualifiedText.Read.LexasL-- ------------------------------------------------------------------------------- Reading-- | Reads an /unsigned/ 'Integral' value in an arbitrary base.readInt::Numa=>a-- ^ the base->(Char->Bool)-- ^ a predicate distinguishing valid digits in this base->(Char->Int)-- ^ a function converting a valid digit character to an 'Int'->ReadSareadIntbaseisDigitvalDigit=readP_to_S(L.readIntPbaseisDigitvalDigit)-- | Read an unsigned number in octal notation.---- >>> readOct "0644"-- [(420,"")]readOct::(Eqa,Numa)=>ReadSareadOct=readP_to_SL.readOctP-- | Read an unsigned number in decimal notation.---- >>> readDec "0644"-- [(644,"")]readDec::(Eqa,Numa)=>ReadSareadDec=readP_to_SL.readDecP-- | Read an unsigned number in hexadecimal notation.-- Both upper or lower case letters are allowed.---- >>> readHex "deadbeef"-- [(3735928559,"")]readHex::(Eqa,Numa)=>ReadSareadHex=readP_to_SL.readHexP-- | Reads an /unsigned/ 'RealFrac' value,-- expressed in decimal scientific notation.readFloat::RealFraca=>ReadSareadFloat=readP_to_SreadFloatPreadFloatP::RealFraca=>ReadPareadFloatP=dotok<-L.lexcasetokofL.Numbern->return$fromRational$L.numberToRationaln_->pfail-- It's turgid to have readSigned work using list comprehensions,-- but it's specified as a ReadS to ReadS transformer-- With a bit of luck no one will use it.-- | Reads a /signed/ 'Real' value, given a reader for an unsigned value.readSigned::(Reala)=>ReadSa->ReadSareadSignedreadPos=readParenFalseread'whereread'r=read''r++(do("-",s)<-lexr(x,t)<-read''sreturn(-x,t))read''r=do(str,s)<-lexr(n,"")<-readPosstrreturn(n,s)-- ------------------------------------------------------------------------------- Showing-- | Show /non-negative/ 'Integral' numbers in base 10.showInt::Integrala=>a->ShowSshowIntn0cs0|n0<0=errorWithoutStackTrace"Numeric.showInt: can't show negative numbers"|otherwise=gon0cs0wheregoncs|n<10=caseunsafeChr(ord'0'+fromIntegraln)ofc@(C#_)->c:cs|otherwise=caseunsafeChr(ord'0'+fromIntegralr)ofc@(C#_)->goq(c:cs)where(q,r)=n`quotRem`10-- Controlling the format and precision of floats. The code that-- implements the formatting itself is in @PrelNum@ to avoid-- mutual module deps.{-# SPECIALIZEshowEFloat::MaybeInt->Float->ShowS,MaybeInt->Double->ShowS#-}{-# SPECIALIZEshowFFloat::MaybeInt->Float->ShowS,MaybeInt->Double->ShowS#-}{-# SPECIALIZEshowGFloat::MaybeInt->Float->ShowS,MaybeInt->Double->ShowS#-}-- | Show a signed 'RealFloat' value-- using scientific (exponential) notation (e.g. @2.45e2@, @1.5e-3@).---- In the call @'showEFloat' digs val@, if @digs@ is 'Nothing',-- the value is shown to full precision; if @digs@ is @'Just' d@,-- then at most @d@ digits after the decimal point are shown.showEFloat::(RealFloata)=>MaybeInt->a->ShowS-- | Show a signed 'RealFloat' value-- using standard decimal notation (e.g. @245000@, @0.0015@).---- In the call @'showFFloat' digs val@, if @digs@ is 'Nothing',-- the value is shown to full precision; if @digs@ is @'Just' d@,-- then at most @d@ digits after the decimal point are shown.showFFloat::(RealFloata)=>MaybeInt->a->ShowS-- | Show a signed 'RealFloat' value-- using standard decimal notation for arguments whose absolute value lies-- between @0.1@ and @9,999,999@, and scientific notation otherwise.---- In the call @'showGFloat' digs val@, if @digs@ is 'Nothing',-- the value is shown to full precision; if @digs@ is @'Just' d@,-- then at most @d@ digits after the decimal point are shown.showGFloat::(RealFloata)=>MaybeInt->a->ShowSshowEFloatdx=showString(formatRealFloatFFExponentdx)showFFloatdx=showString(formatRealFloatFFFixeddx)showGFloatdx=showString(formatRealFloatFFGenericdx)-- | Show a signed 'RealFloat' value-- using standard decimal notation (e.g. @245000@, @0.0015@).---- This behaves as 'showFFloat', except that a decimal point-- is always guaranteed, even if not needed.---- @since 4.7.0.0showFFloatAlt::(RealFloata)=>MaybeInt->a->ShowS-- | Show a signed 'RealFloat' value-- using standard decimal notation for arguments whose absolute value lies-- between @0.1@ and @9,999,999@, and scientific notation otherwise.---- This behaves as 'showFFloat', except that a decimal point-- is always guaranteed, even if not needed.---- @since 4.7.0.0showGFloatAlt::(RealFloata)=>MaybeInt->a->ShowSshowFFloatAltdx=showString(formatRealFloatAltFFFixeddTruex)showGFloatAltdx=showString(formatRealFloatAltFFGenericdTruex){- | Show a floating-point value in the hexadecimal format,similar to the @%a@ specifier in C's printf.  >>> showHFloat (212.21 :: Double) ""  "0x1.a86b851eb851fp7"  >>> showHFloat (-12.76 :: Float) ""  "-0x1.9851ecp3"  >>> showHFloat (-0 :: Double) ""  "-0x0p+0"-}showHFloat::RealFloata=>a->ShowSshowHFloat=showString.fmtwherefmtx|isNaNx="NaN"|isInfinitex=(ifx<0then"-"else"")++"Infinity"|x<0||isNegativeZerox='-':cvt(-x)|otherwise=cvtxcvtx|x==0="0x0p+0"|otherwise=casefloatToDigits2xofr@([],_)->error$"Impossible happened: showHFloat: "++showr(d:ds,e)->"0x"++showd++fracds++"p"++show(e-1)-- Given binary digits, convert them to hex in blocks of 4-- Special case: If all 0's, just drop it.fracdigits|allZdigits=""|otherwise="."++hexdigitswherehexds=casedsof[]->""[a]->hexDigita000""[a,b]->hexDigitab00""[a,b,c]->hexDigitabc0""a:b:c:d:r->hexDigitabcd(hexr)hexDigitabcd=showHex(8*a+4*b+2*c+d)allZxs=casexsofx:more->x==0&&allZmore[]->True-- ----------------------------------------------------------------------------- Integer printing functions-- | Shows a /non-negative/ 'Integral' number using the base specified by the-- first argument, and the character representation specified by the second.showIntAtBase::(Integrala,Showa)=>a->(Int->Char)->a->ShowSshowIntAtBasebasetoChrn0r0|base<=1=errorWithoutStackTrace("Numeric.showIntAtBase: applied to unsupported base "++showbase)|n0<0=errorWithoutStackTrace("Numeric.showIntAtBase: applied to negative number "++shown0)|otherwise=showIt(quotRemn0base)r0whereshowIt(n,d)r=seqc$-- stricter than necessarycasenof0->r'_->showIt(quotRemnbase)r'wherec=toChr(fromIntegrald)r'=c:r-- | Show /non-negative/ 'Integral' numbers in base 16.showHex::(Integrala,Showa)=>a->ShowSshowHex=showIntAtBase16intToDigit-- | Show /non-negative/ 'Integral' numbers in base 8.showOct::(Integrala,Showa)=>a->ShowSshowOct=showIntAtBase8intToDigit

[8]ページ先頭

©2009-2025 Movatter.jp