Using rand() with a NSUInteger to get random element from array - ios

In an objective C script I am trying to get a random string from an NSArray by using
int idx = rand() % self.adviceList.count;
However, every time it executes it throws an EXC_ARITHMETIC error. My question is twofold:
1) How do I get the code to run
2) is there a more portable way to generate a random int/NSUInteger in iOS programming?

The code you posted should work. Probably self.adviceList.count returns zero and this is a reason of EXC_ARITHMETIC.
As Mattt Thompson wrote in his article:
Use arc4random() and its related functions.
Specifically, to generate a random number between 0 and N - 1, use
arc4random_uniform(), which avoids modulo bias.

Try using arc4random_uniform( num ) which takes in an unsigned int
rand() returns an int and random() returns a long so it is possible modulus doesn't like unsigned numbers?

Related

Is that a bug, when I send zero to to funtion luaO_ceillog2?

I'a reading lua source code which version is 5.3. And i found the function
int luaO_ceillog2 (unsigned int x) in lobject.c file doest't take a special discuss for 0. When 0 was send to this fuction, it would return 32. Does this is a bug? I was confused.
luaO_ceillog2 is a function that's only used internally. Its name infers that it calculates ceil (maximum number that's not less than) of log2 of the argument.
Mathematically, logbx is only valid for x who is positive. So 0 is not a valid argument for this function, I don't think this counts as a bug.

How to do Integer division in Dart?

I have trouble with integer division in Dart as it gives me error: 'Breaking on exception: type 'double' is not a subtype of type 'int' of 'c'.'
Here's the following code:
int a = 500;
int b = 250;
int c;
c = a / b; // <-- Gives warning in Dart Editor, and throws an error in runtime.
As you see, I was expecting that the result should be 2, or say, even if division of 'a' or 'b' would have a result of a float/double value, it should be converted directly to integer value, instead of throwing error like that.
I have a workaround by using .round()/.ceil()/.floor(), but this won't suffice as in my program, this little operation is critical as it is called thousands of times in one game update (or you can say in requestAnimationFrame).
I have not found any other solution to this yet, any idea? Thanks.
Dart version: 1.0.0_r30798
That is because Dart uses double to represent all numbers in dart2js. You can get interesting results, if you play with that:
Code:
int a = 1;
a is int;
a is double;
Result:
true
true
Actually, it is recommended to use type num when it comes to numbers, unless you have strong reasons to make it int (in for loop, for example). If you want to keep using int, use truncating division like this:
int a = 500;
int b = 250;
int c;
c = a ~/ b;
Otherwise, I would recommend to utilize num type.
Integer division is
c = a ~/ b;
you could also use
c = (a / b).floor();
c = (a / b).ceil();
if you want to define how fractions should be handled.
Short Answer
Use c = a ~/ b.
Long Answer
According to the docs, int are numbers without a decimal point, while double are numbers with a decimal point.
Both double and int are subtypes of num.
When two integers are divided using the / operator, the result is evaluated into a double. And the c variable was initialized as an integer. There are at least two things you can do:
Use c = a ~/ b.
The ~/ operator returns an int.
Use var c;. This creates a dynamic variable that can be assigned to any type, including a double and int and String etc.
Truncating division operator
You can use the truncating division operator ~/ to get an integer result from a division operation:
4 ~/ 2; // 2 (int)
Division operator
The regular division operator / will always return a double value at runtime (see the docs):
for (var i = 4; i == 4; i = 3) {
i / 2; // 2 (double)
}
Runtime versus compile time
You might have noticed that I wrote a loop for the second example (for the regular division operator) instead of 4 / 2.
The reason for this is the following:
When an expression can be evaluated at compile time, it will be simplified at that stage and also be typed accordingly. The compiler would simply convert 4 / 2 to 2 at compile time, which is then obviously an int. The loop prevents the compiler from evaluating the expression.
As long as your division happens at runtime (i.e. with variables that cannot be predicted at compile time), the return types of the / (double) and ~/ (int) operators will be the types you will see for your expressions at runtime.
See this fun example for further reference.
Conclusion
Generally speaking, the regular division operator / always returns a double value and truncate divide can be used to get an int result instead.
Compiler optimization might, however, cause some funky results :)

pow operation wih long numbers in objective c

I am trying to make the operation pow(49999994,13) which results 1.220701e+100. But when i do in objective c i got the result -9223372036854775808. How can I do this operation in Objective-C correctly?
There is no pow operator in Objective-C, so use C or NSDecimalNumber (preferred).
pow
NSLog(#"%f",(double)pow(49999994,13)); // OK 12207012207044960421719...
NSLog(#"%f",(long long int)pow(49999994,13)); // WRONG -9223372036854775808
-92233... results from using a long long int instead a double.
NSDecimalNumber
As noted by Martin R, the proper way to do it in Objective-C is NSDecimalNumber, which produces as many accurate digits as possible followed by zeros.
NSDecimalNumber *n = [NSDecimalNumber decimalNumberWithString:#"49999994e0"];
n = [n decimalNumberByRaisingToPower:13];
NSLog(#"nsdecimal %#",n);
Compare the results:
accurate 12207012207044960931467189309843359073812548192494216675520514965298161665721254575494908505339305984
nsdecimal 12207012207044960931467189309843359073800000000000000000000000000000000000000000000000000000000000000
pow 12207012207044960421719677106210881027530912788496417091073101786581413645039745611250537465292783616.000000
If you see the method declaration of pow() it is something like this :
double pow(double, double);
And you saved the result into long int or you printed using integer(s) specifiers, resulting in exceeding the max limit of long int.
You can use it as :
double result=pow(49999994,13);

iOS arc4random NOT beginning from 0

i used arc4random to create a random number, is there a way to tell arc4random to begin at for example -5 instead of 0? because i want to create a random number in the range of
-3,4 to 4,3, im not that good in iOS developing yet, so what other possiblities do i have if that wont work with arc4random (Links are appreciated if theres a guide or something like that)
First of all, use arc4random_uniform to get a random number in the desired absolute range (for -3 to 4 it would be 7): arc4random_uniform(7).
You might also see the form arc4random() % max, but that will introduce a modulo bias making the distribution less random, arc4random_uniform is prefered.
Afterwards, adjust your lower bound:
arc4random_uniform(7) - 3
apple docs
Since arc4random() % n returns an integer from 0..n-1, arc4random() % (n - k) + k returns one from k..n-1. Plug in k=-5. Is that what you need?
If you want it to start at -5 instead of 0, just subtract 5.
If you want to create a random number in the range of -3 to 4, just create a number from 0 to 7 and subtract 3 from it.
The arc4random function gives you a number from zero to 4,294,967,295. To change that to a number from 0 to 7, just divide by 613,566,756. (Or use arc4random_uniform to avoid any bias.)

How do I generate random numbers on iOS?

What is the best way to generate random numbers using Objective-C on iOS?
If I use (int)((double) rand() / ((double)(RAND_MAX) + (double) 1) * 5.0) to generate a number from 0 to 4, every time I start the program on the iPhone it generates the same numbers to start off with.
There is a very similar question here on StackOverFlow. Here is one of the better solutions (no need for seeding):
int r = arc4random() % 5;
i use
#define RANDOM_SEED() srandom(time(NULL))
#define RANDOM_INT(__MIN__, __MAX__) ((__MIN__) + random() % ((__MAX__+1) - (__MIN__)))
so you can give a min and max
You should seed the random number generator with the current time.
srand(time(0));
How random do you need? If you want random enough for crypto, then use SecRandomCopyBytes().
Call srand() at the start of your program, it'll reseed random number generator
Simple function for random number generation:
int r = arc4random() % 42; // generate number up to 42 (limit)

Resources