How to calculate ((Integer)^(double)) % (Integer) in java? - java

I am trying to calculate the value of (10^5.102103)%24 that is 10 raised to power 5.102103 modulus 24 in Java ?
Which is the best and accurate method to do because
int a;
double b;
int m;
Calculate (a^b)%m
Where a can be very large like upto 10^9
b can be any double or float value which can be large
and m is any Integer
Example ---How you can calculate the value of
(10^10002.3443)%10000007
I know Math.pow(a,b) function works for small a and b only
While BigInteger function Uses only modPow(a,b) where a and b should be integer only(Correct me if i am wrong)

Unfortunately, it's not possible using the normal Java data types to get a correct answer to this. If you use double to store the exponent, you introduce an error, because double won't store most decimal numbers exactly. When you write double b = 10002.3443; the number that is stored in b is actually 10002.34430000000065774656832218170166015625. Even though it looks like 10002.3443 when you print it, that's a trick of the way Java prints numbers - basically it chooses the decimal number with the least number of decimal places that would be represented by that double.
Now this difference looks insignificant. But the difference between 10^10002.3443 and 10^10002.34430000000065774656832218170166015625 is approximately 3.346 x 10^9990, which is a 9991-digit number. Now, what will this difference become when we apply the modulus operator?
(10^10002.34430000000065774656832218170166015625 % 10000007) - (10^10002.3443 % 10000007)
= (10^10002.34430000000065774656832218170166015625 - 10^10002.3443) % 10000007
= (3.346 x 10^9990) % 10000007 (approximately)
Now, it's anybody's guess what that actually comes to. But you've got a better chance of being struck by lightning than of getting the correct answer, if you use double at any point in the calculation.
The other option might be BigDecimal. But the problem is that 10^10002.3443 is irrational - it's not a terminating decimal, so it can't be represented correctly in a BigDecimal.
So Java doesn't have a data type that will allow you to perform the calculation that you want to perform.
You are going to have to invent your own data type, then work out how to do all the bit-crunching to implement exponentiation and modulus. This is a huge project, and I suggest you start out by getting yourself a PhD in mathematics.
(Note: Obviously, I am using ^ to indicate exponentiation and x to indicate multiplication in the above, even though this is not the normal Java convention)

Let's think back to discrete math!
Given y = a b (mod m), we know that
y = ((a mod m)^b) mod m
For example, if we have
a = 2, b = 6, m = 5
a raised to the power of b is 64. 64 mod m is 64 % 5 == 4. Let's check our algorithm:
4 == ((a mod m)^b) mod m
4 == ((2 mod 5)^6) mod 5
...
4 == 64 % 5
4 == 4
This doesn't really help us all too much (in its current form), so let's use modular arithmetic at every step to save the day.
int a = 10;
int m = 10000007;
double b = 10002.3443;
int holder = (int) b;
double delta = b - holder; // as close as we're going to get
int total = 1;
for (int i = 0; i < holder; i++) {
total *= (a % m); // multiply by the modulus
total %= m; // take the modulus again
}
total *= (Math.round(Math.pow(a, delta)) % m);
total %= m;

Related

Modulo division vs remainder division java

I have learned a lot from my last question hopefully I don't make the same mistakes again:)
This stems from a previous question. Here is what I THINK I know:
For ints in java (I assume in all languages but Iā€™m asking in JAVA specifically):
1/3 = 0
1%3 = 1
I was stumped as to why i%j = i when i < j and a previous poster explained how this worked and also stated that "First, in Java, % is the remainder (not modulo) operator, which has slightly different semantics...."
Their explanation was perfect for what I needed. However, I was confused by their quote because I was always taught that in mathematics modular == remainder division.
How does one execute modular division in JAVA and are there pitfalls to watch for when trying to use % as a modulus operator?
mathematicaly, modulo is division with remainder.
7 mod 4 = 1 R3
see:
n = a * m + r
The modulo operator in Java (like in most other languages) gives only the remainder part and not i dont know, if it works with negative numbers correct.
In Detail, mathematicaly the modulo is allways positive. That is the differece to the modulo operator in java.
a mod n = b, if there is a number k existing with a = b + kn
and 0 <= b < n
That means, if you take -14 mod 4:
-14 = b + k * 4 //lets take -3 for k
-14 = b + -3 * 4
-14 = b - 12
-2 = b
that would be wrong (mathematically) becaouse b is negative.
so we need to take -4 for k
-14 = b + -4 * 4
-14 = b + 16
2 = b
that is the correct answer. In this case only the sign is the difference, but if you take -15 mod 4 you will get -3 in java and most other languages, but the mathematically correct answer would be 1 (-15 + 16)
using java, you will get the negative values.
You may be confused by the "modulo operator" in arithmetic, which is the same as the % operator in Java and similar languages, I don't think there is such thing as "modular division". The % operator in java will always return the integer remainder from repeated division between two numbers. Just like in arithmetic, (i % j) = i where i < j and i >= 0. The result of the operation is less than j.

Using bitwise operator to divide by 0 (Simulation of division by 0) [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
We know that we can use bitwise operators to divide any two numbers. For example:
int result = 10 >> 1; //reult would be 5 as it's like dividing 10 by 2^1
Is there any chance we can divide a number by 0 using bits manipulation?
Edit 1: If I rephrase my question, I want to actually divide a number by zero and break my machine. How do I do that?
Edit 2: Let's forget about Java for a moment. Is it feasible for a machine to divide a number by 0 regardless of the programming language used?
Edit 3: As it's practically impossible to do this, is there a way we can simulate this using a really small number that approaches 0?
Another edit: Some people mentioned that CPU hardware prevents division by 0. I agree, there won't be a direct way to do it. Let's see this code for example:
i = 1;
while(0 * i != 10){
i++;
}
Let's assume that there is no cap on the maximum value of i. In this case there would be no compiler error nor the CPU would resist this. Now, I want my machine to find the number that's when multiplied with 0 gives me a result (which is obviously never going to happen) or die trying.
So, as there is a way to do this. How can I achieve this by directly manipulating bits?
Final Edit: How to perform binary division in Java without using bitwise operators? (I'm sorry, it purely contradicts the title).
Note: I've tried simulating divison by 0 and posted my answer. However, I'm looking for a faster way of doing it.
If what you want is a division method faster than division by repeated subtraction (which you posted), and that will run indefinitely when you try to divide by zero, you can implement your own version of the Goldschmidt division, and not throw an error when the divisor is zero.
The algorithm works like this:
1. Create an estimate for the factor f
2. Multiply both the dividend and the divisor by f
3. If the divisor is close enough to 1
Return the dividend
4. Else
Go back to step 1
Normally, we would need to scale down the dividend and the divisor before starting, so that 0 < divisor < 1 is satisfied. In this case, since we are going to divide by zero, there's no need for this step. We also need to choose an arbitrary precision beyond which we consider the result good enough.
The code, with no check for divisor == 0, would be like this:
static double goldschmidt(double dividend, double divisor) {
double epsilon = 0.0000001;
while (Math.abs(1.0 - divisor) > epsilon) {
double f = 2.0 - divisor;
dividend *= f;
divisor *= f;
}
return dividend;
}
This is much faster than the division by repeated subtraction method, since it converges to the result quadratically instead of linearly. When dividing by zero, it would not really matter, since both methods won't converge. But if you try to divide by a small number, such as 10^(-9), you can clearly see the difference.
If you don't want the code to run indefinitely, but to return Infinity when dividing by zero, you can modify it to stop when dividend reaches Infinity:
static double goldschmidt(double dividend, double divisor) {
double epsilon = 0.0000001;
while (Math.abs(1.0 - divisor) > 0.0000001 && !Double.isInfinite(dividend)) {
double f = 2.0 - divisor;
dividend *= f;
divisor *= f;
}
return dividend;
}
If the starting values for dividend and divisor are such that dividend >= 1.0 and divisor == 0.0, you will get Infinity as a result after, at most, 2^10 iterations. That's because the worst case is when dividend == 1 and you need to multiply it by two (f = 2.0 - 0.0) 1024 times to get to 2^1024, which is greater than Double.MAX_VALUE.
The Goldschmidt division was implemented in AMD Athlon CPUs. If you want to read about some lower level details, you can check this article:
Floating Point Division and Square Root Algorithms and Implementation
in the AMD-K7
TM
Microprocessor.
Edit:
Addressing your comments:
Note that the code for the Restoring Division method you posted iterates 2048 (2^11) times. I lowered the value of n in your code to 1024, so we could compare both methods doing the same number of iterations.
I ran both implementations 100000 times with dividend == 1, which is the worst case for Goldschmidt, and measured the running time like this:
long begin = System.nanoTime();
for (int i = 0; i < 100000; i++) {
goldschmidt(1.0, 0.0); // changed this for restoringDivision(1) to test your code
}
long end = System.nanoTime();
System.out.println(TimeUnit.NANOSECONDS.toMillis(end - begin) + "ms");
The running time was ~290ms for Goldschmidt division and ~23000ms (23 seconds) for your code. So this implementation was about 80x faster in this test. This is expected, since in one case we are doing double multiplications and in the other we are working with BigInteger.
The advantage of your implementation is that, since you are using BigInteger, you can make your result as large as BigInteger supports, while the result here is limited by Double.MAX_VALUE.
In practice, when dividing by zero, the Goldschmidt division is doubling the dividend, which is equivalent to a shift left, at each iteration, until it reaches the maximum possible value. So the equivalent using BigInteger would be:
static BigInteger divideByZero(int dividend) {
return BigInteger.valueOf(dividend)
.shiftLeft(Integer.MAX_VALUE - 1 - ceilLog2(dividend));
}
static int ceilLog2(int n) {
return (int) Math.ceil(Math.log(n) / Math.log(2));
}
The function ceilLog2() is necessary, so that the shiftLeft() will not cause an overflow. Depending on how much memory you have allocated, this will probably result in a java.lang.OutOfMemoryError: Java heap space exception. So there is a compromise to be made here:
You can get the division simulation to run really fast, but with a result upper bound of Double.MAX_VALUE,
or
You can get the result to be as big as 2^(Integer.MAX_VALUE - 1), but it would probably take too much memory and time to get to that limit.
Edit 2:
Addressing your new comments:
Please note that no division is happening in your updated code. It's just trying to find the biggest possible BigInteger
First, let us show that the Goldschmidt division degenerates into a shift left when divisor == 0:
static double goldschmidt(double dividend, double divisor) {
double epsilon = 0.0000001;
while (Math.abs(1.0 - 0.0) > 0.0000001 && !Double.isInfinite(dividend)) {
double f = 2.0 - 0.0;
dividend *= f;
divisor = 0.0 * f;
}
return dividend;
}
The factor f will always be equal to 2.0 and the first while condition will always be true. So if we eliminate the redundancies:
static double goldschmidt(double dividend, 0) {
while (!Double.isInfinite(dividend)) {
dividend *= 2.0;
}
return dividend;
}
Assuming dividend is an Integer, we can do the same multiplication using a shift left:
static int goldschmidt(int dividend) {
while (...) {
dividend = dividend << 1;
}
return dividend;
}
If the maximum value we can reach is 2^n, we need to loop n times. When dividend == 1, this is equivalent to:
static int goldschmidt(int dividend) {
return 1 << n;
}
When the dividend > 1, we need to subtract ceil(log2(dividend)) to prevent an overflow:
static int goldschmidt(int dividend) {
return dividend << (n - ceil(log2(dividend));
}
Thus showing that the Goldschmidt division is equivalent to a shift left if divisor == 0.
However, shifting the bits to the left would pad bits on the right with 0. Try running this with a small dividend and left shift it (once or twice to check the results). This thing will never get to 2^(Integer.MAX_VALUE - 1).
Now that we've seen that a shift left by n is equivalent to a multiplication by 2^n, let's see how the BigInteger version works. Consider the following examples that show we will get to 2^(Integer.MAX_VALUE - 1) if there is enough memory available and the dividend is a power of 2:
For dividend = 1
BigInteger.valueOf(dividend).shiftLeft(Integer.MAX_VALUE - 1 - ceilLog2(dividend))
= BigInteger.valueOf(1).shiftLeft(Integer.MAX_VALUE - 1 - 0)
= 1 * 2^(Integer.MAX_VALUE - 1)
= 2^(Integer.MAX_VALUE - 1)
For dividend = 1024
BigInteger.valueOf(dividend).shiftLeft(Integer.MAX_VALUE - 1 - ceilLog2(dividend))
= BigInteger.valueOf(1024).shiftLeft(Integer.MAX_VALUE - 1 - 10)
= 1024 * 2^(Integer.MAX_VALUE - 1)
= 2^10 * 2^(Integer.MAX_VALUE - 1 - 10)
= 2^(Integer.MAX_VALUE - 1)
If dividend is not a power of 2, we will get as close as we can to 2^(Integer.MAX_VALUE - 1) by repeatedly doubling the dividend.
Your requirement is impossible.
The division by 0 is mathematically impossible. The concept just don't exist, so there is no way to simulate it.
If you were actually trying to do limits operation (divide by 0+ or 0-) then there is still no way to do it using bitwise as it will only allow you to divide by power of two.
Here an exemple using bitwise operation only to divide by power of 2
10 >> 1 = 5
Looking at the comments you posted, if what you want is simply to exit your program when an user try to divide by 0 you can simply validate it :
if(dividant == 0)
System.exit(/*Enter here the exit code*/);
That way you will avoid the ArithmeticException.
After exchanging a couple of comments with you, it seems like what you are trying to do is crash the operating system dividing by 0.
Unfortunately for you, as far as I know, any language that can be written on a computer are validated enought to handle the division by 0.
Just think to a simple calculator that you pay 1$, try to divide by 0 and it won't even crash, it will simply throw an error msg. This is probably validated at the processor level anyway.
Edit
After multiple edits/comments to your question, it seems like you are trying to retrieve the Infinity dividing by a 0+ or 0- that is very clause to 0.
You can achieve this with double/float division.
System.out.println(1.0f / 0.0f);//prints infinity
System.out.println(1.0f / -0.0f);//prints -Infinity
System.out.println(1.0d / 0.0d);//prints infinity
System.out.println(1.0d / -0.0d);//prints -Infinity
Note that even if you write 0.0, the value is not really equals to 0, it is simply really close to it.
No, there isn't, since you can only divide by a power of 2 using right shift.
One way to simulate division of unsigned integers (irrespective of divisor used) is by division by repeated subtraction:
BigInteger result = new BigInteger("0");
int divisor = 0;
int dividend = 2;
while(dividend >= divisor){
dividend = dividend - divisor;
result = result.add(BigInteger.ONE);
}
Second way to do this is by using Restoring Division algorithm (Thanks #harold) which is way faster than the first one:
int num = 10;
BigInteger den = new BigInteger("0");
BigInteger p = new BigInteger(new Integer(num).toString());
int n = 2048; //Can be changed to find the biggest possible number (i.e. upto 2^2147483647 - 1). Currently it shows 2^2048 - 1 as output
den = den.shiftLeft(n);
BigInteger q = new BigInteger("0");
for(int i = n; i > 0; i -= 1){
q = q.shiftLeft(1);
p = p.multiply(new BigInteger("2"));
p = p.subtract(den);
if(p.compareTo(new BigInteger("0")) == 1
|| p.compareTo(new BigInteger("0")) == 0){
q = q.add(new BigInteger("1"));
} else {
p = p.add(den);
}
}
System.out.println(q);
As others have indicated, you cannot mathematically divide by 0.
However if you want methods to divide by 0, there are some constants in Double you could use. For example you could have a method
public static double divide(double a, double b){
return b == 0 ? Double.NaN : a/b;
}
or
public static double posLimitDivide(double a, double b){
if(a == 0 && b == 0)
return Double.NaN;
return b == 0 ? (a > 0 ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY) : a/b;
Which would return the limit of a/x where x approaches +b.
These should be ok, as long as you account for it in whatever methods use them. And by OK I mean bad, and could cause indeterminate behavior later if you're not careful. But it is a clear way to indicate the result with an actual value rather than an exception.

Compute the remainder of multiplying two long number?

I am writing a code for a crypto method to compute x^d modulo n using Repeated Squaring
public static long repeatedSquaring(long x, long d, long n){
x = x%n;
boolean dj = d % 2 == 1;
long c = dj ? x : 1;
d = d / 2;
while (d > 0){
dj = d % 2 == 1;
x = x * x % n; //Here
if (dj)
c = c * x % n; //and here..
d = d / 2;
}
return c;
}
This code work fine when n is small. But with n > sqrt(Long.MAX_VALUE)it gives an unexpected result.
Because with x ā‰ˆ n, we can have x*x > Long.MAX_VALUE and then the modulo operator give an incorrect value assign to x (or c).
So, my question is, how we can compute (A * B) % N (all are long type) using only math related method.
I don't want to use BigInteger (BigA.multiply(BigB).remainder(BigN) or we can use BigX.modPow(BigD, BigN) directly for the big problem).
I think that a normal computing will run faster than String computing? Morever with my problem, all temp values are long type 'enough'.
And I wonder that the solution will work fine with the worst case: A, B, N <ā‰ˆ Long.MAX_VALUE.
multiplying can be done in log(B) time simliar to exponentiation
if(b is odd) a+multiply(2*a,(b-1)/2) mod N
else multiply(2*a,b/2) mod N
this works till longvalue/2
http://en.wikipedia.org/wiki/Montgomery_reduction might be more optimum
Really, the short answer is that you need to use BigInteger, even if you don't want to. As you've discovered, the approach you're currently taking will overflow the bounds of a long; even if you improve the algorithm, you still can't get more than 64 bits into the answer with a long.
You say you're using this for crypto; but 64-bit public key crypto is so weak that it is worse than not having it (because it gives a false sense of security). Even 1024 bits is not enough these days for public key, and 64 bits could be cracked more or less instantaneously.
Note that this is not the same as symmetric crypto, where the keys can be much smaller. (But even there, 64 bits is not enough to stop even an amateur hacker.)
See this question, where it was pointed out that 64-bit RSA can be cracked in a fraction of a second... and that was four years ago!

How can I round manually?

I'd like to round manually without the round()-Method.
So I can tell my program that's my number, on this point i want you to round.
Let me give you some examples:
Input number: 144
Input rounding: 2
Output rounded number: 140
Input number: 123456
Input rounding: 3
Output rounded number: 123500
And as a litte addon maybe to round behind the comma:
Input number: 123.456
Input rounding: -1
Output rounded number: 123.460
I don't know how to start programming that...
Has anyone a clue how I can get started with that problem?
Thanks for helping me :)
I'd like to learn better programming, so i don't want to use the round and make my own one, so i can understand it a better way :)
A simple way to do it is:
Divide the number by a power of ten
Round it by any desired method
Multiply the result by the same power of ten in step 1
Let me show you an example:
You want to round the number 1234.567 to two decimal positions (the desired result is 1234.57).
x = 1234.567;
p = 2;
x = x * pow(10, p); // x = 123456.7
x = floor(x + 0.5); // x = floor(123456.7 + 0.5) = floor(123457.2) = 123457
x = x / pow(10,p); // x = 1234.57
return x;
Of course you can compact all these steps in one. I made it step-by-step to show you how it works. In a compact java form it would be something like:
public double roundItTheHardWay(double x, int p) {
return ((double) Math.floor(x * pow(10,p) + 0.5)) / pow(10,p);
}
As for the integer positions, you can easily check that this also works (with p < 0).
Hope this helps
if you need some advice how to start,
step by step write down calculations what you need to do to get from 144,2 --> 140
replace your math with java commands, that should be easy, but if you have problem, just look here and here
public static int round (int input, int places) {
int factor = (int)java.lang.Math.pow(10, places);
return (input / factor) * factor;
}
Basically, what this does is dividing the input by your factor, then multiplying again. When dividing integers in languages like Java, the remainder of the division is dropped from the results.
edit: the code was faulty, fixed it. Also, the java.lang.Math.pow is so that you get 10 to the n-th power, where n is the value of places. In the OP's example, the number of places to consider is upped by one.
Re-edit: as pointed out in the comments, the above will give you the floor, that is, the result of rounding down. If you don't want to always round down, you must also keep the modulus in another variable. Like this:
int mod = input % factor;
If you want to always get the ceiling, that is, rounding up, check whether mod is zero. If it is, leave it at that. Otherwise, add factor to the result.
int ceil = input + (mod == 0 ? 0 : factor);
If you want to round to nearest, then get the floor if mod is smaller than factor / 2, or the ceiling otherwise.
Divide (positive)/Multiply (negative) by the "input rounding" times 10 - 1 (144 / (10 * (2 - 1)). This will give you the same in this instance. Get the remainder of the last digit (4). Determine if it is greater than or equal to 5 (less than). Make it equal to 0 or add 10, depending on the previous answer. Multiply/Divide it back by the "input rounding" times 10 - 1. This should give you your value.
If this is for homework. The purpose is to teach you to think for yourself. I may have given you the answer, but you still need to write the code by yourself.
Next time, you should write your own code and ask what is wrong
For integers, one way would be to use a combination of the mod operator, which is the percent symbol %, and the divide operator. In your first example, you would compute 144 % 10, resulting in 4. And compute 144 / 10, which gives 14 (as an integer). You can compare the result of the mod operation to half of the denominator, to find out if you should round the 14 up to 15 or not (in this case not), and then multiply back by the denominator to get your answer.
In psuedo code, assuming n is the number to round, p is the power of 10 representing the position of the significant digits:
denom = power(10, p)
remainder = n % denom
dividend = n / denom
if (remainder < denom/2)
return dividend * denom
else
return (dividend + 1) * denom

Random Number generation Issues

This question was asked in my interview.
random(0,1) is a function that generates integers 0 and 1 randomly.
Using this function how would you design a function that takes two integers a,b as input and generates random integers including a and b.
I have No idea how to solve this.
We can do this easily by bit logic (E,g, a=4 b=10)
Calculate difference b-a (for given e.g. 6)
Now calculate ceil(log(b-a+1)(Base 2)) i.e. no of bits required to represent all numbers b/w a and b
now call random(0,1) for each bit. (for given example range will be b/w 000 - 111)
do step 3 till the number(say num) is b/w 000 to 110(inclusive) i.e. we need only 7 levels since b-a+1 is 7.So there are 7 possible states a,a+1,a+2,... a+6 which is b.
return num + a.
I hate this kind of interview Question because there are some
answer fulfilling it but the interviewer will be pretty mad if you use them. For example,
Call random,
if you obtain 0, output a
if you obtain 1, output b
A more sophisticate answer, and probably what the interviewer wants is
init(a,b){
c = Max(a,b)
d = log2(c) //so we know how much bits we need to cover both a and b
}
Random(){
int r = 0;
for(int i = 0; i< d; i++)
r = (r<<1)| Random01();
return r;
}
You can generate random strings of 0 and 1 by successively calling the sub function.
So we have randomBit() returning 0 or 1 independently, uniformly at random and we want a function random(a, b) that returns a value in the range [a,b] uniformly at random. Let's actually make that the range [a, b) because half-open ranges are easier to work with and equivalent. In fact, it is easy to see that we can just consider the case where a == 0 (and b > 0), i.e. we just want to generate a random integer in the range [0, b).
Let's start with the simple answer suggested elsewhere. (Forgive me for using c++ syntax, the concept is the same in Java)
int random2n(int n) {
int ret = n ? randomBit() + (random2n(n - 1) << 1) : 0;
}
int random(int b) {
int n = ceil(log2(b)), v;
while ((v = random2n(n)) >= b);
return v;
}
That is-- it is easy to generate a value in the range [0, 2^n) given randomBit(). So to get a value in [0, b), we repeatedly generate something in the range [0, 2^ceil(log2(b))] until we get something in the correct range. It is rather trivial to show that this selects from the range [0, b) uniformly at random.
As stated before, the worst case expected number of calls to randomBit() for this is (1 + 1/2 + 1/4 + ...) ceil(log2(b)) = 2 ceil(log2(b)). Most of those calls are a waste, we really only need log2(n) bits of entropy and so we should try to get as close to that as possible. Even a clever implementation of this that calculates the high bits early and bails out as soon as it exits the wanted range has the same expected number of calls to randomBit() in the worst case.
We can devise a more efficient (in terms of calls to randomBit()) method quite easily. Let's say we want to generate a number in the range [0, b). With a single call to randomBit(), we should be able to approximately cut our target range in half. In fact, if b is even, we can do that. If b is odd, we will have a (very) small chance that we have to "re-roll". Consider the function:
int random(int b) {
if (b < 2) return 0;
int mid = (b + 1) / 2, ret = b;
while (ret == b) {
ret = (randomBit() ? mid : 0) + random(mid);
}
return ret;
}
This function essentially uses each random bit to select between two halves of the wanted range and then recursively generates a value in that half. While the function is fairly simple, the analysis of it is a bit more complex. By induction one can prove that this generates a value in the range [0, b) uniformly at random. Also, it can be shown that, in the worst case, this is expected to require ceil(log2(b)) + 2 calls to randomBit(). When randomBit() is slow, as may be the case for a true random generator, this is expected to waste only a constant number of calls rather than a linear amount as in the first solution.
function randomBetween(int a, int b){
int x = b-a;//assuming a is smaller than b
float rand = random();
return a+Math.ceil(rand*x);
}

Categories

Resources