How to select range of values when using arc4random() - ios

Can I set a range of numbers when using arc4random()? For example 50-100 only.

As pointed out in other posts below, it is better to use arc4random_uniform. (When this answer was originally written, arc4random_uniform was not available). Besides avoiding the modulo bias of arc4random() % x, it also avoids a seeding problem with arc4random when used recursively in short timeframes.
arc4random_uniform(4)
will generate 0, 1, 2 or 3. Thus you could use:
arc4random_uniform(51)
and merely add 50 to the result to get a range between 50 & 100 (inclusive).

To expand upon JohnK comment.
It is suggested that you use the following function to return a ranged random number:
arc4random_uniform(51)
which will return a random number in the range 0 to 50.
Then you can add your lower bounds to this like:
arc4random_uniform(51) + 50
which will return a random number in the range 50 to 100.
The reason we use arc4random_uniform(51) over arc4random() % 51 is to avoid the modulo bias. This is highlighted in the man page as follows:
arc4random_uniform(upper_bound) will return a uniformly distributed random number less than upper_bound. arc4random_uniform() is recommended over constructions like ``arc4random() % upper_bound'' as it avoids "modulo bias" when the upper bound is not a power of two.
In short you get a more evenly distributed random number generated.

int fromNumber = 10;
int toNumber = 30;
int randomNumber = (arc4random()%(toNumber-fromNumber))+fromNumber;
Will generate randon number between 10 and 30, i.e. 11,12,13,14......29

You can use this code for generating random values with range:
//range from 50 to 100
int num1 = (arc4random() % 50) + 50; or
int num1 = arc4random_uniform(50) + 50;
//range from 0-100
int num1 = arc4random() % 100; or
int num1 = arc4random_uniform(100);

In Swift you can use this (inspired by answer of #Justyn)
func generateRandomKey(fromRange rangeFrom:Int, toRange rangeTo:Int) -> Int{
let theKey = arc4random_uniform(UInt32(rangeTo - rangeFrom)) + UInt32(rangeFrom)
return Int(theKey)
}
Will always give you a random range Integer.

In many situations 10 thru 30 would mean inclusive, (includes 10 and 30) ...
int fromNumber = 10;
int toNumber = 30;
toNumber ++;
int randomNumber = (arc4random()%(toNumber-fromNumber))+fromNumber;
Notice the difference toNumber - fromNumber is now 21 ... (20+1) which yields the possible results of 0 thru 20 (inclusive) which when added to fromNumber (10) results in 10 thru 30 (inclusive).

Related

Round up to a 10s in Dart

I'm doing pagination and I'm wondering how I can take a number such as 11 and round it to 20.
Other cases:
1 should round to 10
501 should round to 510
10 should round to 10
Basically I have cards and there are 10 cards per page and so if there are 11 cards there should be 2 pages.
To round a number up to a multiple of some factor, you can do:
/// Round [number] up to a multiple of [factor].
///
/// The [factor] must be greater than zero.
int roundUp(int number, int factor) {
if (factor < 1) throw RangeError.range(factor, 1, null, "factor");
number += factor - 1;
return number - (number % factor);
}
There is a corresponding roundDown which you can defined roundUp in terms of:
int roundDown(int number, int factor) {
if (factor < 1) throw RangeError.range(factor, 1, null, "factor");
return number - (number % factor);
}
int roundUp(int number, int factor) => roundDown(number + (factor - 1), factor);
This rounds towards plus/minus infinity. If you want to round towards/away from zero instead, you can use:
int roundTowardsZero(int number, int factor) {
if (factor < 1) throw RangeError.range(factor, 1, null, "factor");
return number - number.remainder(factor);
}
int roundAwayFromZero(int number, int factor) =>
roundTowardsZero(number + number.sign * (factor - 1), factor);
Because this approach uses only integers, it's relatively safe from precision loss, but it can overflow at the very end of the integer range (or if you use very, very large factors). If you want to be safe against that, we need to add a check for whether number + factor - 1 overflows. In most practical uses, that won't matter.
All you have to do is:
var test = 11;
print((test / 10).ceil() * 10); // 20
Dividing the number by 10 (in this case it's 11) will result in 1.1.
When you do (1.1).ceil(), you will get 2.
Now you multiply by 10 to get it to a power of 10.
var data = 12.62;
print(data.ceil());
Will output
13

arc4random() gives negative Number in iOS

Sometime arc4random() gives negative number also in objective C.
My code is as follow:
Try 1:
long ii = arc4random();
Try 2:
int i = arc4random();
How can I only get positivite random number?
Thank you,
No, it's always positive as it returns an unsigned 32-bit integer (manpage):
u_int32_t arc4random(void);
You are treating it as a signed integer, which is incorrect.
You should use the arc4random_uniform() function. this is the most common random function used.
arc4random_uniform() function
Returns a random number between 0 and the inserted parameter minus 1.
For example arc4random_uniform(3) may return 0, 1 or 2 but not 3.
Example
u_int32_t randomPositiveNo = arc4random_uniform(5) + 1; //to get the range 1 - 5

Min and Max Functions Not Working Swift

I'm making a game and I've been trying to produce random movement. This is my code.
let actualDuration = NSTimeInterval(random(min(): CGFloat(3.0), max: CGFloat(4.0)))
The min and max aren't working please help.
Unlike the .NET Framework or the JDK, there isn't a function that takes min and max parameters to generate a random number. :(
If you want to generate a random number between 3 and 4, you should use the arc4random_uniform function to generate a number between 0 and 999 first and then divide that number by 1000 and plus 3:
let randomNumber = Double(arc4random_uniform(1000))
let actualDuration = CGFloat(randomNumber / 1000 + 3)
Let me explain how this works.
randomNumber is between 0 and 999 right? Now when you divide it by 1000, it becomes a number less than 1. i.e. 0 ~ 0.999. And you add this number to 3, the result becomes a random number between 3 and 4, which is what you wanted.
If you want a more precise double, you can generate a number between 0 and 9999 and divide it by 10000. You know what I mean!
#Ethan Marcus
try like this
let minValue = 3
let maxValue = 4
let actualDuration = NSTimeInterval(minValue + (random() % (maxValue - minValue)))

Rounding to specific value?

I need to round a number, let's say 543 to either the hundreds or the tens place. It could be either one, as it's part of a game and this stage can ask you to do one or the other.
So for example, it could ask, "Round number to nearest tens", and if the number was 543, they would have to enter in 540.
However, I don't see a function that you can specify target place value to round at. I know there's an easy solution, I just can't think of one right now.
From what I see, the round function rounds the last decimal place?
Thanks
To rounding to 100's place
NSInteger num=543;
NSInteger deci=num%100;//43
if(deci>49){
num=num-deci+100;//543-43+100 =600
}
else{
num=num-deci;//543-43=500
}
To round to 10's place
NSInteger num=543;
NSInteger deci=num%10;//3
if(deci>4){
num=num-deci+100;//543-3+10 =550
}
else{
num=num-deci;//543-3=540
}
EDIT:
Tried to merge the above in one:
NSInteger num=543;
NSInteger place=100; //rounding factor, 10 or 100 or even more.
NSInteger condition=place/2;
NSInteger deci=num%place;//43
if(deci>=condition){
num=num-deci+place;//543-43+100 =600.
}
else{
num=num-deci;//543-43=500
}
You may just use an algorithm in your code:
For example, lets say that you need to round up a number to hundred's place.
int c = 543
int k = c % 100
if k > 50
c = (c - k) + 100
else
c = c - k
To round numbers, you can use the modulus operator, %.
The modulus operator gives you the remainder after division.
So 543 % 10 = 3, and 543 % 100 = 43.
Example:
int place = 10;
int numToRound=543;
// Remainder is 3
int remainder = numToRound%place;
if(remainder>(place/2)) {
// Called if remainder is greater than 5. In this case, it is 3, so this line won't be called.
// Subtract the remainder, and round up by 10.
numToRound=(numToRound-remainder)+place;
}
else {
// Called if remainder is less than 5. In this case, 3 < 5, so it will be called.
// Subtract the remainder, leaving 540
numToRound=(numToRound-remainder);
}
// numToRound will output as 540
NSLog(#"%i", numToRound);
Edit: My original answer was submitted before it was ready, because I accidentally hit a key to submit it. Oops.

Scaling a number between two values

If I am given a floating point number but do not know beforehand what range the number will be in, is it possible to scale that number in some meaningful way to be in another range? I am thinking of checking to see if the number is in the range 0<=x<=1 and if not scale it to that range and then scale it to my final range. This previous post provides some good information, but it assumes the range of the original number is known beforehand.
You can't scale a number in a range if you don't know the range.
Maybe what you're looking for is the modulo operator. Modulo is basically the remainder of division, the operator in most languages is is %.
0 % 5 == 0
1 % 5 == 1
2 % 5 == 2
3 % 5 == 3
4 % 5 == 4
5 % 5 == 0
6 % 5 == 1
7 % 5 == 2
...
Sure it is not possible. You can define range and ignore all extrinsic values. Or, you can collect statistics to find range in run time (i.e. via histogram analysis).
Is it really about image processing? There are lots of related problems in image segmentation field.
You want to scale a single random floating point number to be between 0 and 1, but you don't know the range of the number?
What should 99.001 be scaled to? If the range of the random number was [99, 100], then our scaled-number should be pretty close to 0. If the range of the random number was [0, 100], then our scaled-number should be pretty close to 1.
In the real world, you always have some sort of information about the range (either the range itself, or how wide it is). Without further info, the answer is "No, it can't be done."
I think the best you can do is something like this:
int scale(x) {
if (x < -1) return 1 / x - 2;
if (x > 1) return 2 - 1 / x;
return x;
}
This function is monotonic, and has a range of -2 to 2, but it's not strictly a scaling.
I am assuming that you have the result of some 2-dimensional measurements and want to display them in color or grayscale. For that, I would first want to find the maximum and minimum and then scale between these two values.
static double[][] scale(double[][] in, double outMin, double outMax) {
double inMin = Double.POSITIVE_INFINITY;
double inMax = Double.NEGATIVE_INFINITY;
for (double[] inRow : in) {
for (double d : inRow) {
if (d < inMin)
inMin = d;
if (d > inMax)
inMax = d;
}
}
double inRange = inMax - inMin;
double outRange = outMax - outMin;
double[][] out = new double[in.length][in[0].length];
for (double[] inRow : in) {
double[] outRow = new double[inRow.length];
for (int j = 0; j < inRow.length; j++) {
double normalized = (inRow[j] - inMin) / inRange; // 0 .. 1
outRow[j] = outMin + normalized * outRange;
}
}
return out;
}
This code is untested and just shows the general idea. It further assumes that all your input data is in a "reasonable" range, away from infinity and NaN.

Resources