@@ -26,7 +26,7 @@ import Base.GMP: ClongMax, CulongMax, CdoubleMax
2626
2727import Base. Math. lgamma_r
2828
29- const ROUNDING_MODE = [0 ]
29+ const ROUNDING_MODE = Cint [0 ]
3030const DEFAULT_PRECISION = [256 ]
3131
3232# Basic type and initialization definitions
@@ -93,29 +93,32 @@ convert(::Type{BigFloat}, x::Real) = BigFloat(x)
9393convert (:: Type{FloatingPoint} , x:: BigInt ) = BigFloat (x)
9494
9595# # BigFloat -> Integer
96- function unsafe_cast (:: Type{Int64} , x:: BigFloat , r :: RoundingMode )
96+ function unsafe_cast (:: Type{Int64} , x:: BigFloat , ri :: Cint )
9797 ccall ((:__gmpfr_mpfr_get_sj ,:libmpfr ), Cintmax_t,
98- (Ptr{BigFloat}, Int32 ), & x, to_mpfr (r) )
98+ (Ptr{BigFloat}, Cint ), & x, ri )
9999end
100- function unsafe_cast (:: Type{UInt64} , x:: BigFloat , r :: RoundingMode )
100+ function unsafe_cast (:: Type{UInt64} , x:: BigFloat , ri :: Cint )
101101 ccall ((:__gmpfr_mpfr_get_uj ,:libmpfr ), Cuintmax_t,
102- (Ptr{BigFloat}, Int32 ), & x, to_mpfr (r) )
102+ (Ptr{BigFloat}, Cint ), & x, ri )
103103end
104104
105- function unsafe_cast {T<:Signed} (:: Type{T} , x:: BigFloat , r :: RoundingMode )
106- unsafe_cast (Int64, x, r ) % T
105+ function unsafe_cast {T<:Signed} (:: Type{T} , x:: BigFloat , ri :: Cint )
106+ unsafe_cast (Int64, x, ri ) % T
107107end
108- function unsafe_cast {T<:Unsigned} (:: Type{T} , x:: BigFloat , r :: RoundingMode )
109- unsafe_cast (UInt64, x, r ) % T
108+ function unsafe_cast {T<:Unsigned} (:: Type{T} , x:: BigFloat , ri :: Cint )
109+ unsafe_cast (UInt64, x, ri ) % T
110110end
111111
112- function unsafe_cast (:: Type{BigInt} , x:: BigFloat , r :: RoundingMode )
112+ function unsafe_cast (:: Type{BigInt} , x:: BigFloat , ri :: Cint )
113113 # actually safe, just keep naming consistent
114114 z = BigInt ()
115115 ccall ((:mpfr_get_z , :libmpfr ), Int32, (Ptr{BigInt}, Ptr{BigFloat}, Int32),
116- & z, & x, to_mpfr (r) )
116+ & z, & x, ri )
117117 z
118118end
119+ unsafe_cast (:: Type{Int128} , x:: BigFloat , ri:: Cint ) = Int128 (unsafe_cast (BigInt,x,ri))
120+ unsafe_cast (:: Type{UInt128} , x:: BigFloat , ri:: Cint ) = UInt128 (unsafe_cast (BigInt,x,ri))
121+ unsafe_cast {T<:Integer} (:: Type{T} , x:: BigFloat , r:: RoundingMode ) = unsafe_cast (T,x,to_mpfr (r))
119122
120123unsafe_trunc {T<:Integer} (:: Type{T} , x:: BigFloat ) = unsafe_cast (T,x,RoundToZero)
121124
@@ -132,21 +135,21 @@ function ceil{T<:Union(Signed,Unsigned)}(::Type{T}, x::BigFloat)
132135 unsafe_cast (T,x,RoundUp)
133136end
134137
138+ function round {T<:Union(Signed,Unsigned)} (:: Type{T} , x:: BigFloat )
139+ (typemin (T) <= x <= typemax (T)) || throw (InexactError ())
140+ unsafe_cast (T,x,ROUNDING_MODE[end ])
141+ end
142+
135143trunc (:: Type{BigInt} , x:: BigFloat ) = unsafe_cast (BigInt, x, RoundToZero)
136144floor (:: Type{BigInt} , x:: BigFloat ) = unsafe_cast (BigInt, x, RoundDown)
137145ceil (:: Type{BigInt} , x:: BigFloat ) = unsafe_cast (BigInt, x, RoundUp)
146+ round (:: Type{BigInt} , x:: BigFloat ) = unsafe_cast (BigInt, x, ROUNDING_MODE[end ])
147+
138148# convert/round/trunc/floor/ceil(Integer, x) should return a BigInt
139149trunc (:: Type{Integer} , x:: BigFloat ) = trunc (BigInt, x)
140150floor (:: Type{Integer} , x:: BigFloat ) = floor (BigInt, x)
141151ceil (:: Type{Integer} , x:: BigFloat ) = ceil (BigInt, x)
142-
143- for Ti in (Int128,UInt128)
144- @eval begin
145- trunc (:: Type{$Ti} , x:: BigFloat ) = ($ Ti)(trunc (BigInt, x))
146- floor (:: Type{$Ti} , x:: BigFloat ) = ($ Ti)(floor (BigInt, x))
147- ceil (:: Type{$Ti} , x:: BigFloat ) = ($ Ti)(ceil (BigInt, x))
148- end
149- end
152+ round (:: Type{Integer} , x:: BigFloat ) = round (BigInt, x)
150153
151154convert (:: Type{Bool} , x:: BigFloat ) = (x != 0 )
152155function convert (:: Type{BigInt} ,x:: BigFloat )
@@ -625,11 +628,11 @@ end
625628maxintfloat (x:: BigFloat ) = BigFloat (2 )^ precision (x)
626629maxintfloat (:: Type{BigFloat} ) = BigFloat (2 )^ get_bigfloat_precision ()
627630
628- to_mpfr (:: RoundingMode{:TiesToEven } ) = 0
629- to_mpfr (:: RoundingMode{:TowardZero } ) = 1
630- to_mpfr (:: RoundingMode{:TowardPositive } ) = 2
631- to_mpfr (:: RoundingMode{:TowardNegative } ) = 3
632- to_mpfr (:: RoundingMode{:AwayFromZero } ) = 4
631+ to_mpfr (:: RoundingMode{:Nearest } ) = Cint ( 0 )
632+ to_mpfr (:: RoundingMode{:ToZero } ) = Cint ( 1 )
633+ to_mpfr (:: RoundingMode{:Up } ) = Cint ( 2 )
634+ to_mpfr (:: RoundingMode{:Down } ) = Cint ( 3 )
635+ to_mpfr (:: RoundingMode{:FromZero } ) = Cint ( 4 )
633636
634637function from_mpfr (c:: Integer )
635638 if c == 0
@@ -687,7 +690,7 @@ function isinteger(x::BigFloat)
687690 return ccall ((:mpfr_integer_p , :libmpfr ), Int32, (Ptr{BigFloat},), & x) != 0
688691end
689692
690- for f in (:ceil , :floor , :trunc , :round )
693+ for f in (:ceil , :floor , :trunc )
691694 @eval begin
692695 function ($ f)(x:: BigFloat )
693696 z = BigFloat ()
@@ -697,6 +700,17 @@ for f in (:ceil, :floor, :trunc, :round)
697700 end
698701end
699702
703+ function round (x:: BigFloat )
704+ z = BigFloat ()
705+ ccall ((:mpfr_rint , :libmpfr ), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Cint), & z, & x, ROUNDING_MODE[end ])
706+ return z
707+ end
708+ function round (x:: BigFloat ,:: RoundingMode{:NearestTiesAway} )
709+ z = BigFloat ()
710+ ccall ((:mpfr_round , :libmpfr ), Int32, (Ptr{BigFloat}, Ptr{BigFloat}), & z, & x)
711+ return z
712+ end
713+
700714function isinf (x:: BigFloat )
701715 return ccall ((:mpfr_inf_p , :libmpfr ), Int32, (Ptr{BigFloat},), & x) != 0
702716end
0 commit comments