X-Git-Url: https://ginac.de/CLN/cln.git//cln.git?a=blobdiff_plain;f=src%2Finteger%2Felem%2Fcl_I_div.cc;h=79a2c6783e0c08356a27bbcbf62520f1ce326abb;hb=740c032627dfc7ac87d90d6e75b5e87e78c9e716;hp=3ff043e4e9737a0b6149519ee6f0cac530834341;hpb=dd9e0f894eec7e2a8cf85078330ddc0a6639090b;p=cln.git diff --git a/src/integer/elem/cl_I_div.cc b/src/integer/elem/cl_I_div.cc index 3ff043e..79a2c67 100644 --- a/src/integer/elem/cl_I_div.cc +++ b/src/integer/elem/cl_I_div.cc @@ -1,15 +1,17 @@ // cl_divide(). // General includes. -#include "cl_sysdep.h" +#include "base/cl_sysdep.h" // Specification. -#include "cl_I.h" +#include "integer/cl_I.h" // Implementation. -#include "cl_N.h" +#include "cln/exception.h" + +namespace cln { // Dividiert zwei Integers x,y >=0 und liefert Quotient und Rest // der Division x/y. Bei y=0 Error. @@ -21,31 +23,60 @@ // x Fixnum >=0 { if (fixnump(y)) // auch y Fixnum >=0 - { var uint32 x_ = FN_to_UL(x); - var uint32 y_ = FN_to_UL(y); - if (y_==0) { cl_error_division_by_0(); } + { var uintV x_ = FN_to_UV(x); + var uintV y_ = FN_to_UV(y); + if (y_==0) { throw division_by_0_exception(); } elif (x_ < y_) // Trivialfall: q=0, r=x goto trivial; - elif (y_ < bit(16)) - // 32-durch-16-Bit-Division - { var uint32 q; - var uint16 r; - divu_3216_3216(x_,y_,q=,r=); - return cl_I_div_t( - /* result.quotient = */ UL_to_I(q), - /* result.remainder = */ L_to_FN((uintL)r) - ); - } else - // volle 32-durch-32-Bit-Division - { var uint32 q; - var uint32 r; - divu_3232_3232(x_,y_,q=,r=); - return cl_I_div_t( - /* result.quotient = */ UL_to_I(q), - /* result.remainder = */ UL_to_I(r) - ); + { + #if (intVsize>32) + if (x_ >= bit(32)) + { if (y_ < bit(32)) + // 64-durch-32-Bit-Division + { var uint64 q; + var uint32 r; + divu_6432_6432(x_,y_,q=,r=); + return cl_I_div_t( + /* result.quotient = */ UQ_to_I(q), + /* result.remainder = */ UL_to_I(r) + ); + } + else + // volle 64-durch-64-Bit-Division + { var uint64 q; + var uint64 r; + divu_6464_6464(x_,y_,q=,r=); + return cl_I_div_t( + /* result.quotient = */ UQ_to_I(q), + /* result.remainder = */ UQ_to_I(r) + ); + } + } + else + #endif + { if (y_ < bit(16)) + // 32-durch-16-Bit-Division + { var uint32 q; + var uint16 r; + divu_3216_3216(x_,y_,q=,r=); + return cl_I_div_t( + /* result.quotient = */ UL_to_I(q), + /* result.remainder = */ L_to_FN((uintL)r) + ); + } + else + // volle 32-durch-32-Bit-Division + { var uint32 q; + var uint32 r; + divu_3232_3232(x_,y_,q=,r=); + return cl_I_div_t( + /* result.quotient = */ UL_to_I(q), + /* result.remainder = */ UL_to_I(r) + ); + } + } } } else @@ -70,7 +101,7 @@ // x in NDS umwandeln, als UDS auffassen: BN_to_NDS_nocopy(x, x_MSDptr=,x_len=,x_LSDptr=); // y in NDS umwandeln, als UDS auffassen: - I_to_NDS_nocopy(y, y_MSDptr=,y_len=,y_LSDptr=,/*cl_true*/cl_false,); + I_to_NDS_nocopy(y, y_MSDptr=,y_len=,y_LSDptr=,/*true*/false,); // dividieren: {var DS q; var DS r; @@ -86,3 +117,4 @@ } // Bit complexity (N = length(x)): O(M(N)). +} // namespace cln