Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Questionable Pull": Fixed BigInt bug & added BigFloat #532

Merged
merged 6 commits into from
Mar 7, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 96 additions & 12 deletions external/gmp_wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,28 +53,112 @@ extern int _jl_mpz_cmp(mpz_t* op1, mpz_t* op2) {
return mpz_cmp(*op1, *op2);
}

extern void _jl_mpz_pow_ui(mpz_t* rop, mpz_t* base, unsigned long int exp) {
mpz_pow_ui(*rop, *base, exp);
}

extern void _jl_mpz_pow_sqrt(mpz_t* rop, mpz_t* op) {
mpz_sqrt(*rop, *op);
}

extern char* _jl_mpz_printf(mpz_t* rop) {
char** pp;
gmp_asprintf(pp, "%Zd", *rop);
return *pp;
char* pp;
int s = gmp_asprintf(&pp, "%Zd", *rop);
return pp;
}

//// MPF

extern void* _jl_mpf_init()
{
mpf_t* flt = malloc(sizeof(mpf_t));
mpf_init(*flt);
return flt;
}

extern void _jl_mpf_clear(mpf_t* rop) {
mpf_clear(*rop);
}

extern void _jl_mpf_set_string(mpf_t* rop, char* s) {
mpf_set_str(*rop, s, 0);
}

extern void _jl_mpf_set_ui(mpf_t* rop, unsigned long int op) {
mpf_set_ui(*rop, op);
}

extern void _jl_mpf_set_si(mpf_t* rop, signed long int op) {
mpf_set_si(*rop, op);
}

extern void _jl_mpf_set_d(mpf_t* rop, double op) {
mpf_set_d(*rop, op);
}

extern void _jl_mpf_set_z(mpf_t* rop, mpz_t* op) {
mpf_set_z(*rop, *op);
}

extern void _jl_mpf_add(mpf_t* rop, mpf_t* op1, mpf_t* op2) {
mpf_add(*rop, *op1, *op2);
}

extern void _jl_mpf_sub(mpf_t* rop, mpf_t* op1, mpf_t* op2) {
mpf_sub(*rop, *op1, *op2);
}

extern void _jl_mpf_mul(mpf_t* rop, mpf_t* op1, mpf_t* op2) {
mpf_mul(*rop, *op1, *op2);
}

extern void _jl_mpf_div(mpf_t* rop, mpf_t* op1, mpf_t* op2) {
mpf_div(*rop, *op1, *op2);
}

extern void _jl_mpf_neg(mpf_t* rop, mpf_t* op1) {
mpf_neg(*rop, *op1);
}

extern void _jl_mpf_abs(mpf_t* rop, mpf_t* op1) {
mpf_abs(*rop, *op1);
}

extern int _jl_mpf_cmp(mpf_t* op1, mpf_t* op2) {
return mpf_cmp(*op1, *op2);
}

extern void _jl_mpf_pow_ui(mpf_t* rop, mpf_t* base, unsigned long int exp) {
mpf_pow_ui(*rop, *base, exp);
}

extern void _jl_mpf_sqrt(mpf_t* rop, mpf_t* op) {
mpf_sqrt(*rop, *op);
}

extern char* _jl_mpf_printf(mpf_t* rop) {
char* pp;
gmp_asprintf(&pp, "%.Ff", *rop);
return pp;
}


//Quick and dirty test of the gmp wrapper code
int main( int argc, const char* argv[] )
{
void* rop = _jl_mpz_init();

void* op1 = _jl_mpz_init();
_jl_mpz_set_string(op1, "123456789123456789123456789123456789");
void* rop = _jl_mpf_init();
void* op1 = _jl_mpf_init();
_jl_mpf_set_string(op1, "123456789123456789123456789123456789");

void* op2 = _jl_mpz_init();
_jl_mpz_set_string(op2, "12345");
void* op2 = _jl_mpf_init();
_jl_mpf_set_string(op2, "12345");

_jl_mpz_add(rop, op1, op2);
_jl_mpf_add(rop, op1, op2);

printf("The sum is %s\n", _jl_mpz_printf(rop));
printf("The sum is %s\n", _jl_mpf_printf(rop));

_jl_mpz_clear(rop);
_jl_mpf_clear(rop);
}


Expand Down
142 changes: 142 additions & 0 deletions jl/bigfloat.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
_jl_libgmp_wrapper = dlopen("libgmp_wrapper")

load("bigint.jl")

type BigFloat <: Float
mpf::Ptr{Void}

function BigFloat(x::String)
z = _jl_BigFloat_init()
ccall(dlsym(_jl_libgmp_wrapper, :_jl_mpf_set_string), Void, (Ptr{Void}, Ptr{Uint8}), z, cstring(x))
b = new(z)
finalizer(b, _jl_BigFloat_clear)
b
end

function BigFloat(x::Float)
z = _jl_BigFloat_init()
ccall(dlsym(_jl_libgmp_wrapper, :_jl_mpf_set_d), Void, (Ptr{Void}, Float), z, x)
b = new(z)
finalizer(b, _jl_BigFloat_clear)
b
end

function BigFloat(x::Uint)
z = _jl_BigFloat_init()
ccall(dlsym(_jl_libgmp_wrapper, :_jl_mpf_set_ui), Void, (Ptr{Void}, Uint), z, x)
b = new(z)
finalizer(b, _jl_BigFloat_clear)
b
end

function BigFloat(x::Int)
z = _jl_BigFloat_init()
ccall(dlsym(_jl_libgmp_wrapper, :_jl_mpf_set_si), Void, (Ptr{Void}, Int), z, x)
b = new(z)
finalizer(b, _jl_BigFloat_clear)
b
end

function BigFloat(x::BigInt)
z = _jl_BigFloat_init()
ccall(dlsym(_jl_libgmp_wrapper, :_jl_mpf_set_z), Void, (Ptr{Void}, Ptr{Void}), z, x.mpz)
b = new(z)
finalizer(b, _jl_BigFloat_clear)
b
end

function BigFloat(z::Ptr{Void})
b = new(z)
finalizer(b, _jl_BigFloat_clear)
b
end
end

convert(::Type{BigFloat}, x::Int8) = BigFloat(x)
convert(::Type{BigFloat}, x::Int16) = BigFloat(x)
convert(::Type{BigFloat}, x::Int32) = BigFloat(x)
convert(::Type{BigFloat}, x::Int64) = BigFloat(x)
convert(::Type{BigFloat}, x::Uint8) = BigFloat(x)
convert(::Type{BigFloat}, x::Uint16) = BigFloat(x)
convert(::Type{BigFloat}, x::Uint32) = BigFloat(x)
convert(::Type{BigFloat}, x::Uint64) = BigFloat(x)

convert(::Type{BigFloat}, x::Float) = BigFloat(x)
convert(::Type{BigFloat}, x::Float32) = BigFloat(x)
convert(::Type{BigFloat}, x::Float64) = BigFloat(x)

promote_rule(::Type{BigFloat}, ::Type{Float32}) = BigFloat
promote_rule(::Type{BigFloat}, ::Type{Float64}) = BigFloat
promote_rule(::Type{BigFloat}, ::Type{Int8}) = BigFloat
promote_rule(::Type{BigFloat}, ::Type{Int16}) = BigFloat
promote_rule(::Type{BigFloat}, ::Type{Int32}) = BigFloat
promote_rule(::Type{BigFloat}, ::Type{Int64}) = BigFloat
promote_rule(::Type{BigFloat}, ::Type{Uint8}) = BigFloat
promote_rule(::Type{BigFloat}, ::Type{Uint16}) = BigFloat
promote_rule(::Type{BigFloat}, ::Type{Uint32}) = BigFloat
promote_rule(::Type{BigFloat}, ::Type{Uint64}) = BigFloat

function +(x::BigFloat, y::BigFloat)
z= _jl_BigFloat_init()
ccall(dlsym(_jl_libgmp_wrapper, :_jl_mpf_add), Void, (Ptr{Void}, Ptr{Void}, Ptr{Void}), z, x.mpf, y.mpf)
BigFloat(z)
end

function -(x::BigFloat)
z= _jl_BigFloat_init()
ccall(dlsym(_jl_libgmp_wrapper, :_jl_mpf_neg), Void, (Ptr{Void}, Ptr{Void}), z, x.mpf)
BigFloat(z)
end

function -(x::BigFloat, y::BigFloat)
z= _jl_BigFloat_init()
ccall(dlsym(_jl_libgmp_wrapper, :_jl_mpf_sub), Void, (Ptr{Void}, Ptr{Void}, Ptr{Void}), z, x.mpf, y.mpf)
BigFloat(z)
end

function *(x::BigFloat, y::BigFloat)
z= _jl_BigFloat_init()
ccall(dlsym(_jl_libgmp_wrapper, :_jl_mpf_mul), Void, (Ptr{Void}, Ptr{Void}, Ptr{Void}), z, x.mpf, y.mpf)
BigFloat(z)
end

function div (x::BigFloat, y::BigFloat)
z= _jl_BigFloat_init()
ccall(dlsym(_jl_libgmp_wrapper, :_jl_mpf_div), Void, (Ptr{Void}, Ptr{Void}, Ptr{Void}), z, x.mpf, y.mpf)
BigFloat(z)
end

function cmp(x::BigFloat, y::BigFloat)
ccall(dlsym(_jl_libgmp_wrapper, :_jl_mpf_cmp), Int, (Ptr{Void}, Ptr{Void}), x.mpf, y.mpf)
end

function pow(x::BigFloat, y::Uint)
z = _jl_BigFloat_init()
ccall(dlsym(_jl_libgmp_wrapper, :_jl_mpf_pow_ui), Void, (Ptr{Void}, Ptr{Void}, Uint), z, x.mpf, y)
BigFloat(z)
end

==(x::BigFloat, y::BigFloat) = cmp(x,y) == 0
<=(x::BigFloat, y::BigFloat) = cmp(x,y) <= 0
>=(x::BigFloat, y::BigFloat) = cmp(x,y) >= 0
<(x::BigFloat, y::BigFloat) = cmp(x,y) < 0
>(x::BigFloat, y::BigFloat) = cmp(x,y) > 0

function string(x::BigFloat)
s=ccall(dlsym(_jl_libgmp_wrapper, :_jl_mpf_printf), Ptr{Uint8}, (Ptr{Void},), x.mpf)
ret = cstring(s) #This copies s.
_jl_free(convert(Ptr{Void},s))
ret
end

function show(x::BigFloat)
print (string(x))
end

function _jl_BigFloat_clear(x::BigFloat)
ccall(dlsym(_jl_libgmp_wrapper, :_jl_mpf_clear), Void, (Ptr{Void},), x.mpf)
end

function _jl_BigFloat_init()
return ccall(dlsym(_jl_libgmp_wrapper, :_jl_mpf_init), Ptr{Void}, ())
end
6 changes: 6 additions & 0 deletions jl/bigint.jl
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ function sqrt(x::BigInt)
BigInt(z)
end

function pow(x::BigInt, y::Uint)
z = _jl_bigint_init()
ccall(dlsym(_jl_libgmp_wrapper, :_jl_mpz_pow_ui), Void, (Ptr{Void}, Ptr{Void}, Uint), z, x.mpz, y)
BigInt(z)
end

==(x::BigInt, y::BigInt) = cmp(x,y) == 0
<=(x::BigInt, y::BigInt) = cmp(x,y) <= 0
>=(x::BigInt, y::BigInt) = cmp(x,y) >= 0
Expand Down
34 changes: 34 additions & 0 deletions test/bigfloat.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

load ("../jl/bigfloat.jl")
a=BigFloat("12.34567890121")
b=BigFloat("12.34567890122")

@assert typeof(a+0.00000000001) == BigFloat
@assert a+0.00000000001 == b
@assert b == a+0.00000000001
@assert !(b == a)
@assert b > a
@assert b >= a
@assert !(b < a)
@assert !(b <= a)

c = BigFloat("24.69135780242")
@assert typeof(a * 2) == BigFloat
@assert a*2 == c
@assert c-a == a
@assert c == a + a
@assert c+1 == a+b

d = BigFloat("-24.69135780242")
@assert typeof(d) == BigFloat
@assert d == -c

#Multiple calls for sanity check, since we're doing direct memory manipulation
@assert string(a) == "12.34567890121"
@assert string(b) == "12.34567890122"
@assert string(c) == "24.69135780242"
@assert string(d) == "-24.69135780242"

@assert div(BigFloat(3), BigFloat(2)) == BigFloat(1)
@assert rem(BigFloat(3), BigFloat(2)) == BigFloat(1)

1 change: 0 additions & 1 deletion test/bigint.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ load ("../jl/bigint.jl")
a=BigInt("123456789012345678901234567890")
b=BigInt("123456789012345678901234567891")


@assert typeof(a+1) == BigInt
@assert a+1 == b
@assert b == a+1
Expand Down