Skip to content

Commit

Permalink
Rename precision-related functions and add them to Float32 and Float64
Browse files Browse the repository at this point in the history
Now get_precision is defined for all T <: FloatingPoint, and returns
24 for Float32 and 53 for Float64 (the effective number of bits in the
mantissa, taking in account the implicit leading bit.

get_bigfloat_precision and set_bigfloat_precision are used to get and set
the defaults for all BigFloats, and the BigComplex case is analogous.
  • Loading branch information
andrioni committed May 3, 2013
1 parent 94ba263 commit 9bff273
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 53 deletions.
7 changes: 3 additions & 4 deletions base/exports.jl
Expand Up @@ -826,13 +826,12 @@ export

# precision
exp10,
prec,
prec2,
get_precision,
get_bigfloat_precision,
get_complex_precision,
set_precision,
set_bigfloat_precision,
set_complex_precision,
with_precision,
with_bigfloat_precision,
with_complex_precision,

# statistics
Expand Down
4 changes: 4 additions & 0 deletions base/floatfuncs.jl
Expand Up @@ -31,6 +31,10 @@ maxintfloat() = maxintfloat(Float64)

integer_valued(x::FloatingPoint) = (trunc(x)==x)&isfinite(x)

## precision, as defined by the effective number of bits in the mantissa ##
get_precision(::Float32) = 24
get_precision(::Float64) = 53

num2hex(x::Float32) = hex(box(Uint32,unbox(Float32,x)),8)
num2hex(x::Float64) = hex(box(Uint64,unbox(Float64,x)),16)

Expand Down
31 changes: 12 additions & 19 deletions base/mpc.jl
Expand Up @@ -4,15 +4,14 @@ export
# Types
MPCComplex,
# Functions
prec2,
get_complex_precision,
set_complex_precision,
with_complex_precision
get_bigcomplex_precision,
set_bigcomplex_precision,
with_bigcomplex_precision

import
Base: (*), +, -, /, <, <<, >>, <=, ==, >, >=, ^, (~), (&), (|), ($), cmp,
complex, convert, div, imag, integer_valued, isfinite, isinf, isnan,
promote_rule, real, show, showcompact, sqrt, string, prec
promote_rule, real, show, showcompact, sqrt, string, get_precision

const ROUNDING_MODE = 0
const DEFAULT_PRECISION = [53, 53]
Expand Down Expand Up @@ -208,38 +207,32 @@ end
# Utility functions
==(x::MPCComplex, y::MPCComplex) = ccall((:mpc_cmp, :libmpc), Int32, (Ptr{Void}, Ptr{Void}), x.mpc, y.mpc) == 0


# TODO: decide if prec and prec2 should be just one method or not.
function prec(x::MPCComplex)
return ccall((:mpc_get_prec, :libmpc), Int, (Ptr{Void},), x.mpc)
end

function prec2(x::MPCComplex)
function get_precision(x::MPCComplex)
a = [0]
b = [0]
ccall((:mpc_get_prec2, :libmpc), Int, (Ptr{Int}, Ptr{Int}, Ptr{Void}), a, b, x.mpc)
return (a[1],b[1])
end

get_complex_precision() = (DEFAULT_PRECISION[1],DEFAULT_PRECISION[end])
function set_complex_precision(x::Int, y::Int)
get_bigcomplex_precision() = (DEFAULT_PRECISION[1],DEFAULT_PRECISION[end])
function set_bigcomplex_precision(x::Int, y::Int)
if x < 2
throw(DomainError())
end
DEFAULT_PRECISION[1], DEFAULT_PRECISION[end] = x, y
end
set_complex_precision(x::(Int,Int)) = set_complex_precision(x...)
set_bigcomplex_precision(x::(Int,Int)) = set_bigcomplex_precision(x...)

iscomplex(::MPCComplex) = true
isfinite(x::MPCComplex) = isfinite(real(x)) && isfinite(imag(x))
isinf(x::MPCComplex) = !isfinite(x)
integer_valued(x::MPCComplex) = imag(x) == 0 && integer_valued(real(x))

function with_complex_precision(f::Function, realprec::Integer, imagprec::Integer)
old_precision = get_complex_precision()
set_complex_precision(realprec, imagprec)
function with_bigcomplex_precision(f::Function, realprec::Integer, imagprec::Integer)
old_precision = get_bigcomplex_precision()
set_bigcomplex_precision(realprec, imagprec)
ret = f()
set_complex_precision(old_precision)
set_bigcomplex_precision(old_precision)
return ret
end

Expand Down
24 changes: 12 additions & 12 deletions base/mpfr.jl
Expand Up @@ -5,17 +5,17 @@ export
MPFRFloat,
# Functions
exp10,
prec,
get_precision,
set_precision,
with_precision
get_bigfloat_precision,
set_bigfloat_precision,
with_bigfloat_precision

import
Base: (*), +, -, /, <, <=, ==, >, >=, ^, besselj, besselj0, besselj1,
bessely, bessely0, bessely1, ceil, cmp, convert, copysign, exp, exp2,
exponent, factorial, floor, integer_valued, iround, isfinite, isinf,
isnan, log, log2, log10, max, min, mod, modf, nextfloat, prevfloat,
promote_rule, rem, round, show, showcompact, sum, sqrt, string, trunc,
get_precision,
# import trigonometric functions
sin, cos, tan, sec, csc, cot, acos, asin, atan, cosh, sinh, tanh,
sech, csch, coth, acosh, asinh, atanh
Expand Down Expand Up @@ -348,12 +348,12 @@ end
<(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_less_p, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}), &(x.mpfr), &(y.mpfr)) != 0
>(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_greater_p, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}), &(x.mpfr), &(y.mpfr)) != 0

function prec(x::MPFRFloat)
function get_precision(x::MPFRFloat)
return ccall((:mpfr_get_prec, :libmpfr), Int, (Ptr{mpfr_struct},), &(x.mpfr))
end

get_precision() = DEFAULT_PRECISION[end]
function set_precision(x::Int)
get_bigfloat_precision() = DEFAULT_PRECISION[end]
function set_bigfloat_precision(x::Int)
if x < 2
throw(DomainError())
end
Expand Down Expand Up @@ -417,11 +417,11 @@ function prevfloat(x::MPFRFloat)
return z
end

function with_precision(f::Function, precision::Integer)
old_precision = get_precision()
set_precision(precision)
function with_bigfloat_precision(f::Function, precision::Integer)
old_precision = get_bigfloat_precision()
set_bigfloat_precision(precision)
ret = f()
set_precision(old_precision)
set_bigfloat_precision(old_precision)
return ret
end

Expand All @@ -446,7 +446,7 @@ function string(x::MPFRFloat)
end
end

show(io::IO, b::MPFRFloat) = print(io, string(b) * " with $(prec(b)) bits of precision")
show(io::IO, b::MPFRFloat) = print(io, string(b) * " with $(get_precision(b)) bits of precision")
showcompact(io::IO, b::MPFRFloat) = print(io, string(b))

end #module
36 changes: 18 additions & 18 deletions test/mpfr.jl
Expand Up @@ -107,29 +107,29 @@ x = MPFRFloat(15.674)
@test_fails sqrt(MPFRFloat(-1))

# precision
old_precision = get_precision()
old_precision = get_bigfloat_precision()
x = MPFRFloat(0)
@test prec(x) == old_precision
set_precision(256)
@test get_precision(x) == old_precision
set_bigfloat_precision(256)
x = MPFRFloat(0)
@test prec(x) == 256
set_precision(old_precision)
z = with_precision(240) do
@test get_precision(x) == 256
set_bigfloat_precision(old_precision)
z = with_bigfloat_precision(240) do
z = x + 20
return z
end
@test float(z) == 20.
@test prec(z) == 240
@test get_precision(z) == 240
x = MPFRFloat(12)
@test prec(x) == old_precision
@test_fails set_precision(1)
@test get_precision(x) == old_precision
@test_fails set_bigfloat_precision(1)

# integer_valued
@test integer_valued(MPFRFloat(12))
@test !integer_valued(MPFRFloat(12.12))

# nextfloat / prevfloat
with_precision(53) do
with_bigfloat_precision(53) do
x = MPFRFloat(12.12)
@test MPFRFloat(nextfloat(12.12)) == nextfloat(x)
@test MPFRFloat(prevfloat(12.12)) == prevfloat(x)
Expand Down Expand Up @@ -174,7 +174,7 @@ y = modf(x)
@test (isnan(y[1]), isinf(y[2])) == (true, true)

# rem
with_precision(53) do
with_bigfloat_precision(53) do
x = MPFRFloat(2)
y = MPFRFloat(1.67)
@test rem(x,y) == rem(2, 1.67)
Expand Down Expand Up @@ -209,13 +209,13 @@ big_array = ones(MPFRFloat, 100)
# promotion
# the array converts everyone to the DEFAULT_PRECISION!
x = MPFRFloat(12)
y = with_precision(60) do
y = with_bigfloat_precision(60) do
MPFRFloat(42)
end
@test [x,y] == [MPFRFloat(12), MPFRFloat(42)]

# log / log2 / log10
with_precision(53) do
with_bigfloat_precision(53) do
x = MPFRFloat(42)
@test log(x) == log(42)
@test isinf(log(MPFRFloat(0)))
Expand All @@ -229,7 +229,7 @@ x = MPFRFloat(42)
end

# exp / exp2 / exp10
with_precision(53) do
with_bigfloat_precision(53) do
x = MPFRFloat(10)
@test exp(x) == exp(10)
@test exp2(x) == 1024
Expand All @@ -252,7 +252,7 @@ y = MPFRFloat(42)

# iround
x = MPFRFloat(42.42)
y = with_precision(256) do
y = with_bigfloat_precision(256) do
MPFRFloat("9223372036854775809.2324")
end
z = BigInt("9223372036854775809")
Expand All @@ -267,7 +267,7 @@ z = BigInt("9223372036854775809")
@test typeof(iround(Uint, x)) == Uint && iround(Uint, x) == 0x2a

# factorial
with_precision(256) do
with_bigfloat_precision(256) do
x = MPFRFloat(42)
@test factorial(x) == factorial(BigInt(42))
x = MPFRFloat(10)
Expand All @@ -277,7 +277,7 @@ with_precision(256) do
end

# bessel functions
with_precision(53) do
with_bigfloat_precision(53) do
@test_approx_eq besselj(4, MPFRFloat(2)) besselj(4, 2.)
@test_approx_eq besselj0(MPFRFloat(2)) besselj0(2.)
@test_approx_eq besselj1(MPFRFloat(2)) besselj1(2.)
Expand All @@ -287,7 +287,7 @@ with_precision(53) do
end

# trigonometric functions
with_precision(53) do
with_bigfloat_precision(53) do
for f in (:sin,:cos,:tan,:sec,:csc,:cot,:acos,:asin,:atan,
:cosh,:sinh,:tanh,:sech,:csch,:coth,:asinh),
j in (-1., -0.5, -0.25, .25, .5, 1.)
Expand Down

0 comments on commit 9bff273

Please sign in to comment.