How to perform division of BigIntegers with bigger denominator than numerator and exponentiating it to 1/x where x is also biginteger - biginteger

I am trying to solve the equation A = ( ( Z/(U.S^v) ) ^ 1/e ) mod n, and all the variables are bigintegers. The denominator is much bigger than the numberator, the numerator being about 50 digits and denominator is of above 250 digits. the answer i get is 0 for the division.
i tried bigdecimal as well, that also gives me same problem.

Related

Why do I get an incorrect output from a modulus operation with negative number

I tried this code on Dart: I get 28.5
void main() {
double modulo = -1.5 % 30.0;
print(modulo);
}
The same code in Javascript returns -1.5
let modulo = -1.5 % 30;
console.log(modulo);
What is the equivalent of the javascript code above in Dart ?
The documentation for num.operator % states (emphasis mine):
Returns the remainder of the Euclidean division. The Euclidean division of two integers a and b yields two integers q and r such that a == b * q + r and 0 <= r < b.abs().
...
The sign of the returned value r is always positive.
See remainder for the remainder of the truncating division.
Meanwhile, num.remainder says (again, emphasis mine):
The result r of this operation satisfies: this == (this ~/ other) * other + r. As a consequence the remainder r has the same sign as the divider this.
So if you use:
void main() {
double modulo = (-1.5).remainder(30.0);
print(modulo);
}
you'll get -1.5.
Note that both values are mathematically correct; there are two different answers that correspond to the two different ways that you can compute a negative quotient when performing integer division. You have a choice between rounding a negative quotient toward zero (also known as truncation) or toward negative infinity (flooring). remainder corresponds to a truncating division, and % corresponds to a flooring division.
An issue was raised about this in the dart-lang repo a while ago. Apparently the % symbol in dart is an "Euclidean modulo operator rather than remainder."
An equivalent of what you are trying to do can be accomplished with
(-1.5).remainder(30.0)

find modulus exponentiation for biginteger in matlab

I want to calculate modulo exponentiation for Biginteger in Matlab.
a^b mod n = d
Example:
a=java.math.BigInteger('878');
b=java.math.BigInteger('8097');
c=java.math.BigInteger('961');
d=modPow(a,b,n)
How can I calculate unknown n in this Biginteger equation if a, b, d are given?
a=35367
b=453467
a^b mod n =16
or
modPow(a,b,n)=16
n=?
If the answer to the equation is equal to, for example, 16 and we want to find the value of n, how do we write the modulo equation to solve the values of n in Matlab, even for larger numbers?
It can be defined that the number n be found up to 1000000 or 10^6.
Thanks.

Convert 64 bit numbers from binary to decimal using uint64

I want to convert 64 bit numbers from binary to decimal. Since dec2bin only supports up to 52 bits, I thought I could roll my own function and use uint64 to go beyond this limit:
function [dec] = my_bin2dec(bin)
v = uint64(length(bin)-1:-1:0);
base = uint64(2).^v;
dec = uint64(sum(uint64(base.*(uint64(bin-'0')))));
end
However, it does not work as expected:
my_bin2dec('111000000000000000000000000000000000001010110101011101000001110')
ans =
8070450532270651392
my_bin2dec('111000000000000000000000000000000000001010110101011101000001111')
ans =
8070450532270651392
Whereas this is the correct result:
(111000000000000000000000000000000000001010110101011101000001110)bin
= (8070450532270651918)dec
(111000000000000000000000000000000000001010110101011101000001111)bin
= (8070450532270651919)dec
What am I missing? It seems like there is some operation still performed using 52bit double arithmetic, but I don't know which one.
I checked if the operations are available for uint64 and it seems that the ones I use (power, times, sum) are there:
>> methods uint64
Methods for class uint64:
abs bitxor diff isinf mod plus sum
accumarray bsxfun display isnan mpower power times
all ceil eq issorted mrdivide prod transpose
and colon find ldivide mtimes rdivide tril
any conj fix le ne real triu
bitand ctranspose floor linsolve nnz rem uminus
bitcmp cummax full lt nonzeros reshape uplus
bitget cummin ge max not round xor
bitor cumprod gt min nzmax sign
bitset cumsum imag minus or sort
bitshift diag isfinite mldivide permute sortrowsc
You were right in saying that
It seems like there is some operation still performed using 52bit double arithmetic.
The problem is in line
dec = uint64(sum(uint64(base.*(uint64(bin-'0')))));
The operation sum(uint64(base.*(uint64(bin-'0')))) gives a double result, which only has about 15 significant digits. That's why your lowest digits are wrong. Subsequent conversion into uint64 doesn't help, because precision has already been lost.
The solution is to sum natively in uint64. This gives a uint64 result with its full precision:
dec = sum(uint64(base.*(uint64(bin-'0'))), 'native');
Had the same thought as #beaker, break it into chunks:
%% dec2bin
x=intmax('uint64')
MSBs = dec2bin( bitshift(x,-32) ,32)
LSBs = dec2bin( bitand(x, hex2dec('FFFFFFFF')) ,32)
y = [MSBs LSBs]
%% bin2dec
MSBs = y(1:32)
LSBs = y(33:64)
z = bitor( bitshift( uint64(bin2dec(MSBs)) , 32 ) , uint64(bin2dec(LSBs)) )
% (now x = z)
Oddly enough, it seems that dec2bin doesn't give an error, but does give incorrect answers for 64 bit numbers:
dec2bin( intmax('uint64') )
ans =
10000000000000000000000000000000000000000000000000000000000000000

Matlab: Error when dividing the covariance matrix

I have an expression which is part of the log-likelihood expression for a Gaussian state space model
express =
\sum_{t=2}^T (x(t) - (A*x(t-1)))^2/2*Q
where T = 5, the number of samples/observations; x is a 2 by T matrix; Q is the covariance matrix of the process noise initialized using eye
x =
0.7311 -1.7152 0.2476 3.6643 -1.2870
0.4360 0.3554 0.1981 0.4168 0.2643
A =
0.1950 -0.9500
1.0000 0
Q =
1 0
0 1
I am getting this error:
Error using /
Matrix dimensions must agree.
This is how I have implemented:
numerator = sum((x(:,2:T)-(A*x(:,1:(T-1)))).^2)
numerator =
2.0732 3.0349 3.2291 1.5365
express = numerator / diag(2*diag(Q))
Should I be taking the diagonal or determinant of Q? Please help in correcting this part. Thank you.
You are squaring the term too early. The (') symbol means you need to take the complex conjugate of the term before multiplying it by the inverse of Q and then the term again. I believe you are trying to calculate this
in which case the term you want to sum over is the following,
term = x(:,2:T)-(A*x(:,1:(T-1));
result = term' * inv(Q) * term
the result of which is a 4x4 matrix. You can then sum this (over both directions I presume). From the (7) in the link you mention, you should need to follow this same procedure three times (for R, Q, and V).

Reverse multiplication of 32-bit numbers

I have two large signed 32-bit numbers (java ints) being multiplied together such that they'll overflow. Actually, I have one of the numbers, and the result. Can I determine what the other operand was?
knownResult = unknownOperand * knownOperand;
Why? I have a string and a suffix being hashed with fnv1a. I know the resulting hash and the suffix, I want to see how easy it is to determine the hash of the original string.
This is the core of fnv1a:
hash ^= byte
hash *= PRIME
It depends. If the multiplier is even, at least one bit must inevitably be lost. So I hope that prime isn't 2.
If it's odd, then you can absolutely reverse it, just multiply by the modular multiplicative inverse of the multiplier to undo the multiplication.
There is an algorithm to calculate the modular multiplicative inverse modulo a power of two in Hacker's Delight.
For example, if the multiplier was 3, then you'd multiply by 0xaaaaaaab to undo (because 0xaaaaaaab * 3 = 1). For 0x01000193, the inverse is 0x359c449b.
You want to solve the equation y = prime * x for x, which you do by division in the finite ring modulo 232: x = y / prime.
Technically you do that by multiplying y with the multiplicative inverse of the prime modulo 232, which can be computed by the extended Euclidean algorithm.
Uh, division? Or am I not understanding the question?
It's not the fastest method, but something very easy to memorise is this:
unsigned inv(unsigned x) {
unsigned xx = x * x;
while (xx != 1) {
x *= xx;
xx *= xx;
}
return x;
}
It returns x**(2**n-1) (as in x*(x**2)*(x**4)*(x**8)*..., or x**(1+2+4+8+...)). As the loop exit condition implies, x**(2**n) is 1 when n is big enough, provided x is odd.
So, x**(2**n-1) equals x**(2**n)/x equals 1/x equals the thing you multiply x by to get the value 1 (mod 2**n). Which you then apply:
knownResult = unknownOperand * knownOperand
knownResult * inv(knownOperand) = unknownOperand * knownOperand * inv(knownOperand)
knownResult * inv(knownOperand) = unknownOperand * 1
or simply:
unknownOperand = knownResult * inv(knownOperand);
But there are faster ways, as given in other answers here. This one's just easy to remember.
Also, obligatory SO "use a library function" answer: BN_mod_inverse().