Skip to content

Commit

Permalink
Merge pull request #532 from choffstein/master
Browse files Browse the repository at this point in the history
"Questionable Pull": Fixed BigInt bug & added BigFloat. Merging the whole thing for now, since it won't affect anything else.
  • Loading branch information
ViralBShah committed Mar 7, 2012
2 parents 53a0f02 + 9d4412d commit 5b8a93b
Show file tree
Hide file tree
Showing 5 changed files with 278 additions and 13 deletions.
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

0 comments on commit 5b8a93b

Please sign in to comment.