arc4random throwing out huge numbers - iphone

In a cocos2d game, I use arc4random to generate random numbers like this:
float x = (arc4random()%10 - 5)*delta;
(delta is the time between updates in the scheduled update method)
NSLog(#"x: %f", x);
I have been checking them like that.
Most of the numbers that I get are like this:
2012-12-29 15:37:18.206 Jumpy[1924:907] x: 0.033444
or
2012-12-29 15:37:18.247 Jumpy[1924:907] x: 0.033369
But for some reason I get numbers like this sometimes:
2012-12-29 15:37:18.244 Jumpy[1924:907] x: 71658664.000000
Edit: Delta is almost always:
2012-12-29 17:01:26.612 Jumpy[2059:907] delta: 0.016590
I thought it should return numbers in a range of -5 to 5 (multiplied by some small number). Why I am getting numbers like this?

arc4random returns a u_int32_t. The u_ part tells you that it's unsigned. So all of the operators inside the parentheses use unsigned arithmetic.
If you perform the subtraction 2 - 5 using unsigned 32-bit arithmetic, you get 232 + 2 - 5 = 232 - 3 = 4294967293 (a “huge number”).
Cast to a signed type before performing the subtraction. Also, prefer arc4random_uniform if your deployment target is iOS 4.3 or later:
float x = ((int)arc4random_uniform(10) - 5) * delta;
If you want the range to include -5 and 5, you need to use 11 instead of 10, because the range [-5,5] (inclusive) contains 11 elements:
float x = ((int)arc4random_uniform(11) - 5) * delta;

arc4random returns a u_int32_t, an unsigned type. The modulus is also performed using unsigned arithmetic, which yields a number between 0 and 9, as expected (by the way, don't ever do this; use arc4random_uniform instead). You then subtract 5, which is interpreted as an unsigned value, yielding a possibly huge positive value due to underflow.
The solution is to explicitly type the 5 by storing it in a variable of signed type or with a suffix (like 5L).

Looks like arc4random % 10 becomes less than 5, and you are working with negative integer later.
What is the value of delta?

Related

Why is x / 100 == 0 when x != 0 in swift? [duplicate]

This question already has answers here:
Is the Swift divide "/" operator not working or have I missed something?
(3 answers)
Division not working properly in Swift
(3 answers)
Closed 1 year ago.
I have created a for loop in which I calculate a few values.
for i in 1...100{
let xValue = i/100
print(xValue) // returns 0 every time except when i == 100
}
This is a recreation of a part of that for loop. Why is it that I do not get the right value for 'xValue'?
For info I have also tried the following:
let xValue: Float = Float(i/100)
And that doesn't work either, despite me being very specific. I must have forgotten something basic about these arithmetic
operators in swift.
When you divide an Int by an Int, the result will be rounded down. Use a floating point type, like Double or Float for more precision.
for i in 1...100 {
let xValue = Float(i)/100
print(xValue)
}
To address your attempted solution - when you do:
let xValue: Float = Float(i/100)
The Int result is first computed in i/100 (and rounded down to 0) then you are casting to a Float.
Therefore, we cast i to a Float before the division so the result is computed as a Float.
Since i and 100 are both integer values, / will do integer division and the result will be truncated to 0.
Even when you do let xValue: Float = Float(i/100), the result of division inside the parentheses is already truncated to 0 before the value can be converted to a Float.
Convert i to a floating-point value before dividing to prevent the result from being truncated.
for i in 1...100{
let xValue = Float(i)/100
print(xValue)
}

How I can get the other part after a division with a modulo operator

When I divide 13 with 3 and use integer numbers the result will be 4.
With mod(13,3) I receive the remainder 1. But how can I get the 4 in Matlab? I think it is not possible to switch to integer numbers for this calculation, isn't it?
You can use the floor function:
result = floor(13/3)
This function always rounds down to the lower integer
You can explicitly use integers:
result = uint32(13)/unit32(3);
You can also use hex numbers:
result = 0xDu32 / 0x3u32;
Note that result will be of type uint32.
Use idivide:
result = idivide(13, 3);
You can specify the rounding method with a third argument, with the default being 'fix', or rounding towards zero. For example, this would round towards negative infinity:
result = idivide(13, 3, 'floor');

Algorithm to convert integer (represented as an array) with base n to integer with base m

I have a, very long, integer. The integer is represented by a array of unsigned chars.
Example: the integer 1234 with base 10 is represented in the array as [4,3,2,1], [2,2,3,2] (base 8) and [2,13,4] (base 16)
Now I want to convert my integer with base n to another integer with base m. In my persued for a answer I came accross Wallar's algorithm, originally from here.
from math import *
def baseExpansion(n,c,b):
j = 0
base10 = sum([pow(c,len(n)-k-1)*n[k] for k in range(0,len(n))])
while floor(base10/pow(b,j)) != 0: j = j+1
return [floor(base10/pow(b,j-p)) % b for p in range(1,j+1)]
At first I thought this was my answer but unfortunately it is not. The problem I have is that the algorithm computes the sum. In my case this is a problem because the variable base10 is of type unsigned integer of 32 bits. Therefore when my integer, represented as a array, has more then 10 digits it can not convert the number anymore. Anyone has a solution?
Here's the school-book algorithm for doing what you're trying. You start with a representation for zero and call it a running total. Then, for each digit of the number to be converted, starting with the most significant and going to the least significant, 1) multiply the running total by the base of the source number and 2) add the digit to the running total. Now all you need is algorithms to do the multiplication and addition (and you can actually do both at once). Here's how to do that: 1) set the current digit to a variable, call it "carry", 2) for each digit in your new number, starting with the least significant and going to the most significant: 2a) set carry to the current digit in the new number times the output base plus carry, 2b) set the current digit to carry mod the output base, 2c) set carry to carry divided by the output base. And that should do it. There is an implementation of what you are trying to do somewhere here: http://www.cis.ksu.edu/~howell/calculator/comparison.html

binary to decimal in objective-c

I want to convert the decimal number 27 into binary such a way that , first the digit 2 is converted and its binary value is placed in an array and then the digit 7 is converted and its binary number is placed in that array. what should I do?
thanks in advance
That's called binary-coded decimal. It's easiest to work right-to-left. Take the value modulo 10 (% operator in C/C++/ObjC) and put it in the array. Then integer-divide the value by 10 (/ operator in C/C++/ObjC). Continue until your value is zero. Then reverse the array if you need most-significant digit first.
If I understand your question correctly, you want to go from 27 to an array that looks like {0010, 0111}.
If you understand how base systems work (specifically the decimal system), this should be simple.
First, you find the remainder of your number when divided by 10. Your number 27 in this case would result with 7.
Then you integer divide your number by 10 and store it back in that variable. Your number 27 would result in 2.
How many times do you do this?
You do this until you have no more digits.
How many digits can you have?
Well, if you think about the number 100, it has 3 digits because the number needs to remember that one 10^2 exists in the number. On the other hand, 99 does not.
The answer to the previous question is 1 + floor of Log base 10 of the input number.
Log of 100 is 2, plus 1 is 3, which equals number of digits.
Log of 99 is a little less than 2, but flooring it is 1, plus 1 is 2.
In java it is like this:
int input = 27;
int number = 0;
int numDigits = Math.floor(Log(10, input)) + 1;
int[] digitArray = new int [numDigits];
for (int i = 0; i < numDigits; i++) {
number = input % 10;
digitArray[numDigits - i - 1] = number;
input = input / 10;
}
return digitArray;
Java doesn't have a Log function that is portable for any base (it has it for base e), but it is trivial to make a function for it.
double Log( double base, double value ) {
return Math.log(value)/Math.log(base);
}
Good luck.

Performing operations on a double returns 0

I have a method that receives a number in a NSString format.
I wish to convert this string to a double which I can use to calculate a temperature.
Here's my method.
NSString *stringTemp = text; // text is a NSString
NSLog(#"%#",stringTemp); // used for debugging
double tempDouble = [stringTemp doubleValue];
NSLog(#"%f",tempDouble); // used for debugging
Please note I put the NSLog commands here just to see if the number was correct. The latter NSLog returns a value of 82.000000 etc. (constantly changes as it's a temperature).
Next I wanted to use this double and convert it to a Celsius value. To do so, I did this:
double celsiusTemp = (5 / 9) * (tempDouble - 32);
Doing this: NSLog(#"%d", celsiusTemp); , or this: NSLog(#"%f", celsiusTemp); both give me a value of 0 in the console. Is there any reason why this would be happening? Have I made a stupid mistake somewhere?
Thank you for your help!
Try doing (5.0 / 9.0). If you only use an int to do math where you are expecting a double to be returned (like 0.55) everything after the decimal place will be lost because the cpu expects an int to be returned.
5 / 9 is the division of two integers, and as such uses integer division, which performs the division normally and then truncates the result. So the result of 5 / 9 is always the integer 0.
Try:
double celsiusTemp = (5.0 / 9) * (tempDouble - 32);
If you evaulate (5/9) as an integer, then it is just 0.