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.
48 lines
1.4 KiB
48 lines
1.4 KiB
// power2p().
|
|
|
|
// General includes.
|
|
#include "cl_sysdep.h"
|
|
|
|
// Specification.
|
|
#include "cln/integer.h"
|
|
|
|
|
|
// Implementation.
|
|
|
|
#include "cl_I.h"
|
|
#include "cl_DS.h"
|
|
|
|
namespace cln {
|
|
|
|
uintL power2p (const cl_I& x) // x > 0
|
|
{
|
|
// Methode 1: Wenn ord2(x) = integer_length(x)-1.
|
|
// Methode 2: Wenn logand(x,x-1) = 0.
|
|
// Methode 3: Wenn das erste Digit /=0 eine Zweierpotenz ist und alle weiteren
|
|
// Digits Null sind.
|
|
if (fixnump(x))
|
|
{ var uintV x_ = FN_to_UV(x);
|
|
if (!((x_ & (x_-1)) == 0)) return 0; // keine Zweierpotenz
|
|
#if (intVsize>32)
|
|
integerlength64(x_,return); // Zweierpotenz: n = integer_length(x)
|
|
#else
|
|
integerlength32(x_,return); // Zweierpotenz: n = integer_length(x)
|
|
#endif
|
|
}
|
|
else
|
|
{ var const uintD* MSDptr;
|
|
var uintC len;
|
|
var const uintD* LSDptr;
|
|
BN_to_NDS_nocopy(x, MSDptr=,len=,LSDptr=); // normalisierte DS zu x bilden.
|
|
var uintD msd = mspref(MSDptr,0);
|
|
if (msd==0) { msshrink(MSDptr); msd = mspref(MSDptr,0); len--; }
|
|
// len = Anzahl der Digits ab MSDptr, len>0, msd = erstes Digit (/=0)
|
|
if (!((msd & (msd-1)) == 0)) return 0; // erstes Digit muß Zweierpotenz sein
|
|
if (DS_test_loop(MSDptr mspop 1,len-1,LSDptr)) return 0; // danach alles Nullen
|
|
{var uintL msdlen;
|
|
integerlengthD(msd, msdlen=);
|
|
return intDsize*(uintL)(len-1) + msdlen; // integer_length(x) als Ergebnis
|
|
}}
|
|
}
|
|
|
|
} // namespace cln
|