From 78e653b08c0ae4301df7897306f6a3cd1c3f10ca Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Tue, 7 May 2013 03:45:32 -0300 Subject: [PATCH] Add ifloor, iceil and itrunc to BigFloat (#3040) They convert to a Int64 if it fits, otherwise to BigInt. --- base/mpfr.jl | 16 +++++++++++++++- test/mpfr.jl | 26 ++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/base/mpfr.jl b/base/mpfr.jl index a7d11c61120cb..b2817a81f76c5 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -21,7 +21,7 @@ import isinf, isnan, ldexp, log, log2, log10, max, min, mod, modf, nextfloat, prevfloat, promote_rule, rem, round, show, showcompact, sum, sqrt, string, trunc, get_precision, exp10, expm1, gamma, lgamma, digamma, - erf, erfc, zeta, log1p, airyai, + erf, erfc, zeta, log1p, airyai, iceil, ifloor, itrunc, # import trigonometric functions sin, cos, tan, sec, csc, cot, acos, asin, atan, cosh, sinh, tanh, sech, csch, coth, acosh, asinh, atanh, atan2 @@ -347,6 +347,20 @@ for f in (:ceil, :floor, :trunc) end end +for (f, g) in ((:iceil, :ceil), (:ifloor, :floor), (:itrunc, :trunc)) + @eval begin + function ($f)(x::BigFloat) + fits = ccall((:mpfr_fits_slong_p, :libmpfr), Int32, (Ptr{BigFloat}, Int32), &x, RoundUp) + if fits != 0 + z = BigFloat() + ccall(($(string(:mpfr_,g)), :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}), &z, &x) + return ccall((:mpfr_get_si, :libmpfr), Clong, (Ptr{BigFloat}, Int32), &z, ROUNDING_MODE[end]) + end + return convert(BigInt, ($g)(x)) + end + end +end + function ^(x::BigFloat, y::Unsigned) z = BigFloat() ccall((:mpfr_pow_ui, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Culong, Int32), &z, &x, y, ROUNDING_MODE[end]) diff --git a/test/mpfr.jl b/test/mpfr.jl index 5a4eb20da27cc..7b5fe3ce718b9 100644 --- a/test/mpfr.jl +++ b/test/mpfr.jl @@ -359,6 +359,32 @@ with_bigfloat_precision(53) do @test ldexp(BigFloat(24.5), 0x48) == ldexp(24.5, 72) end +# ceil / iceil / floor / ifloor / trunc / itrunc +x = BigFloat("28273.2312487489135135135") +y = BigInt(28273) +z = BigInt(28274) +a = BigFloat("123456789012345678901234567890.2414") +b = BigInt("123456789012345678901234567890") +c = BigInt("123456789012345678901234567891") +@test ceil(x) == z +@test typeof(ceil(x)) == BigFloat +@test floor(x) == y +@test typeof(floor(x)) == BigFloat +@test trunc(x) == y +@test typeof(trunc(x)) == BigFloat +@test iceil(x) == z +@test typeof(iceil(x)) == Int64 +@test ifloor(x) == y +@test typeof(ifloor(x)) == Int64 +@test itrunc(x) == y +@test typeof(itrunc(x)) == Int64 +@test iceil(a) == c +@test typeof(iceil(a)) == BigInt +@test ifloor(a) == b +@test typeof(ifloor(a)) == BigInt +@test itrunc(a) == b +@test typeof(itrunc(a)) == BigInt + # basic arithmetic # Signed addition a = BigFloat("123456789012345678901234567890")