You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
3.4 KiB
99 lines
3.4 KiB
// logtest().
|
|
|
|
// General includes.
|
|
#include "cl_sysdep.h"
|
|
|
|
// Specification.
|
|
#include "cln/integer.h"
|
|
|
|
|
|
// Implementation.
|
|
|
|
#include "cl_I.h"
|
|
#include "cl_DS.h"
|
|
|
|
namespace cln {
|
|
|
|
cl_boolean logtest (const cl_I& x, const cl_I& y)
|
|
{
|
|
// Methode:
|
|
// Fixnums separat behandeln.
|
|
// Sei oBdA x die kürzere der beiden Zahlen (in Digits).
|
|
// x echt kürzer und x<0 -> [eines der most signif. intDsize+1 Bits von y ist 1] Ja.
|
|
// Beide gleich lang oder x>=0 ->
|
|
// Kann mich auf die untersten length(x) Digits beschraenken.
|
|
// Mit AND durchlaufen, abbrechen (mit "Ja") falls /=0. Am Ende: Nein.
|
|
if (fixnump(x))
|
|
if (fixnump(y))
|
|
// beides Fixnums
|
|
{ if ((x.word & y.word & cl_combine(0,~(cl_uint)0))==0)
|
|
return cl_false;
|
|
else
|
|
return cl_true;
|
|
}
|
|
else
|
|
// x Fixnum, y Bignum, also ist x echt kürzer
|
|
{ if (FN_V_minusp(x,FN_to_V(x))) return cl_true; // x<0 -> ja.
|
|
// x>=0. Kombiniere x mit den pFN_maxlength letzten Digits von y.
|
|
{var const uintD* yLSDptr;
|
|
var uintV x_ = FN_to_V(x);
|
|
BN_to_NDS_nocopy(y, ,,yLSDptr=);
|
|
#if (pFN_maxlength > 1)
|
|
doconsttimes(pFN_maxlength-1,
|
|
if (lsprefnext(yLSDptr) & (uintD)x_) return cl_true;
|
|
x_ = x_ >> intDsize;
|
|
);
|
|
#endif
|
|
if (lsprefnext(yLSDptr) & (uintD)x_) return cl_true;
|
|
return cl_false;
|
|
}}
|
|
else
|
|
if (fixnump(y))
|
|
// x Bignum, y Fixnum, analog wie oben, nur x und y vertauscht
|
|
{ if (FN_V_minusp(y,FN_to_V(y))) return cl_true; // y<0 -> ja.
|
|
// y>=0. Kombiniere y mit den pFN_maxlength letzten Digits von x.
|
|
{var const uintD* xLSDptr;
|
|
var uintV y_ = FN_to_V(y);
|
|
BN_to_NDS_nocopy(x, ,,xLSDptr=);
|
|
#if (pFN_maxlength > 1)
|
|
doconsttimes(pFN_maxlength-1,
|
|
if (lsprefnext(xLSDptr) & (uintD)y_) return cl_true;
|
|
y_ = y_ >> intDsize;
|
|
);
|
|
#endif
|
|
if (lsprefnext(xLSDptr) & (uintD)y_) return cl_true;
|
|
return cl_false;
|
|
}}
|
|
else
|
|
// x,y Bignums
|
|
{ var const uintD* xMSDptr;
|
|
var uintC xlen;
|
|
var const uintD* yMSDptr;
|
|
var uintC ylen;
|
|
BN_to_NDS_nocopy(x, xMSDptr=,xlen=,);
|
|
BN_to_NDS_nocopy(y, yMSDptr=,ylen=,);
|
|
// Beachte: xlen>0, ylen>0.
|
|
if (!(xlen==ylen))
|
|
// beide verschieden lang
|
|
{ if (xlen<ylen)
|
|
{ // x ist die echt kürzere DS.
|
|
if ((sintD)mspref(xMSDptr,0)<0) // der echt kürzere ist negativ?
|
|
return cl_true;
|
|
// Der echt kürzere ist positiv.
|
|
yMSDptr = yMSDptr mspop (ylen-xlen);
|
|
}
|
|
else
|
|
{ // y ist die echt kürzere DS.
|
|
if ((sintD)mspref(yMSDptr,0)<0) // der echt kürzere ist negativ?
|
|
return cl_true;
|
|
// Der echt kürzere ist positiv.
|
|
xMSDptr = xMSDptr mspop (xlen-ylen);
|
|
xlen = ylen;
|
|
} }
|
|
// Nach gemeinsamen Bits in xMSDptr/xlen/.. und yMSDptr/xlen/..
|
|
// suchen:
|
|
return and_test_loop_msp(xMSDptr,yMSDptr,xlen);
|
|
}
|
|
}
|
|
|
|
} // namespace cln
|