{-# LANGUAGE Trustworthy #-}{-# LANGUAGE CPP, MagicHash, UnboxedTuples, NoImplicitPrelude #-}{-# OPTIONS_GHC -O2 #-}{-# OPTIONS_HADDOCK not-home #-}------------------------------------------------------------------------------- |-- Module : GHC.Float.ConversionUtils-- Copyright : (c) Daniel Fischer 2010-- License : see libraries/base/LICENSE---- Maintainer : cvs-ghc@haskell.org-- Stability : internal-- Portability : non-portable (GHC Extensions)---- Utilities for conversion between Double/Float and Rational------------------------------------------------------------------------------- #include "MachDeps.h" moduleGHC.Float.ConversionUtils(elimZerosInteger ,elimZerosInt# )whereimportGHC.Base importGHC.Integer #if WORD_SIZE_IN_BITS < 64 importGHC.IntWord64 #endif default() #if WORD_SIZE_IN_BITS < 64 #define TO64 integerToInt64 toByte64#::Int64#->Int#toByte64#i=word2Int#(and#255##(int2Word#(int64ToInt#i)))-- Double mantissae have 53 bits, too much for Int#elim64#::Int64#->Int#->(#Integer,Int##)elim64#ne=casezeroCount(toByte64#n)oft|isTrue#(e<=#t)->(#int64ToInteger(uncheckedIShiftRA64#ne),0##)|isTrue#(t<#8#)->(#int64ToInteger(uncheckedIShiftRA64#nt),e-#t#)|otherwise->elim64#(uncheckedIShiftRA64#n8#)(e-#8#) #else #define TO64 integerToInt -- Double mantissae fit it Int#elim64# ::Int#->Int#->(#Integer,Int##)elim64# :: Int# -> Int# -> (# Integer, Int# #) elim64# =Int# -> Int# -> (# Integer, Int# #) elimZerosInt# #endif {-# INLINEelimZerosInteger #-}elimZerosInteger ::Integer->Int#->(#Integer,Int##)elimZerosInteger :: Integer -> Int# -> (# Integer, Int# #) elimZerosInteger m :: Integer m e :: Int# e =Int# -> Int# -> (# Integer, Int# #) elim64# (TO64m)eelimZerosInt# ::Int#->Int#->(#Integer,Int##)elimZerosInt# :: Int# -> Int# -> (# Integer, Int# #) elimZerosInt# n :: Int# n e :: Int# e =caseInt# -> Int# zeroCount (Int# -> Int# toByte# Int# n )oft :: Int# t |Int# -> Bool isTrue#(Int# e Int# -> Int# -> Int# <=#Int# t )->(#Int# -> Integer smallInteger(Int# -> Int# -> Int# uncheckedIShiftRA#Int# n Int# e ),0##)|Int# -> Bool isTrue#(Int# t Int# -> Int# -> Int# <#8#)->(#Int# -> Integer smallInteger(Int# -> Int# -> Int# uncheckedIShiftRA#Int# n Int# t ),Int# e Int# -> Int# -> Int# -#Int# t #)|Bool otherwise ->Int# -> Int# -> (# Integer, Int# #) elimZerosInt# (Int# -> Int# -> Int# uncheckedIShiftRA#Int# n 8#)(Int# e Int# -> Int# -> Int# -#8#){-# INLINEzeroCount #-}zeroCount ::Int#->Int#zeroCount :: Int# -> Int# zeroCount i :: Int# i =caseBA zeroCountArr ofBA ba :: ByteArray# ba ->ByteArray# -> Int# -> Int# indexInt8Array#ByteArray# ba Int# i toByte# ::Int#->Int#toByte# :: Int# -> Int# toByte# i :: Int# i =Word# -> Int# word2Int#(Word# -> Word# -> Word# and#255##(Int# -> Word# int2Word#Int# i ))dataBA =BA ByteArray#-- Number of trailing zero bits in a bytezeroCountArr ::BA zeroCountArr :: BA zeroCountArr =letmkArr :: State# d -> ByteArray# mkArr s :: State# d s =caseInt# -> State# d -> (# State# d, MutableByteArray# d #) forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #) newByteArray#256#State# d s of(#s1 :: State# d s1 ,mba :: MutableByteArray# d mba #)->caseMutableByteArray# d -> Int# -> Int# -> State# d -> State# d forall d. MutableByteArray# d -> Int# -> Int# -> State# d -> State# d writeInt8Array#MutableByteArray# d mba 0#8#State# d s1 ofs2 :: State# d s2 ->letfillA :: Int# -> Int# -> Int# -> State# d -> State# d fillA step :: Int# step val :: Int# val idx :: Int# idx st :: State# d st |Int# -> Bool isTrue#(Int# idx Int# -> Int# -> Int# <#256#)=caseMutableByteArray# d -> Int# -> Int# -> State# d -> State# d forall d. MutableByteArray# d -> Int# -> Int# -> State# d -> State# d writeInt8Array#MutableByteArray# d mba Int# idx Int# val State# d st ofnx :: State# d nx ->Int# -> Int# -> Int# -> State# d -> State# d fillA Int# step Int# val (Int# idx Int# -> Int# -> Int# +#Int# step )State# d nx |Int# -> Bool isTrue#(Int# step Int# -> Int# -> Int# <#256#)=Int# -> Int# -> Int# -> State# d -> State# d fillA (2#Int# -> Int# -> Int# *#Int# step )(Int# val Int# -> Int# -> Int# +#1#)Int# step State# d st |Bool otherwise =State# d st incaseInt# -> Int# -> Int# -> State# d -> State# d fillA 2#0#1#State# d s2 ofs3 :: State# d s3 ->caseMutableByteArray# d -> State# d -> (# State# d, ByteArray# #) forall d. MutableByteArray# d -> State# d -> (# State# d, ByteArray# #) unsafeFreezeByteArray#MutableByteArray# d mba State# d s3 of(#_,ba :: ByteArray# ba #)->ByteArray# ba incaseState# RealWorld -> ByteArray# forall d. State# d -> ByteArray# mkArr State# RealWorld realWorld#ofb :: ByteArray# b ->ByteArray# -> BA BA ByteArray# b