High-precision random numbers on iOS - iphone

I have been trying this for a while but thus far haven't had any luck.
What is the easiest way to retrieve a random number between two very precise numbers on iOS?
For example, I want a random number between 41.37783830549337 and 41.377730629131634, how would I accomplish this?
Thank you so much in advance!
Edit: I tried this:
double min = 41.37783830549337;
double max = 41.377730629131634;
double test = ((double)rand() / RAND_MAX) * (max - min) + min;
NSLog(#"Min:%lf, max:%lf, result:%lf",min,max,test);
But the results weren't quite as precise as I was hoping, and ended up like this::
Min:41.377838, max:41.377731, result:41.377838

You can normalise the output of rand to any range you want:
((double)rand() / RAND_MAX) * (max - min) + min
[Note: This is pure C, I'm assuming it works equivalently in Obj-C.]
[Note 2: Replace double with the data-type of your choice as appropriate.]
[Note 3: Replace rand with the random-number source of your choice as appropriate.]

Related

limit random complex number to a given range

I can get the real part of a random number to stay withing a given range but the complex part of the number doesn't stay within the range I set. see matlab / octave code below.
xmin=-.5
xmax=1
n=3
x=xmin+rand(1,n)*(xmax-xmin)+(rand(1,n)-(xmax-xmin))*1i
x=x(:)
The real part works but the complex part isn't limited to -0.5 to 1
0.2419028288441536 - 0.6579427654754871i
0.2712527227134944 - 1.451964497492678i
0.3245051849394858 - 1.107556052779179i
You have two mistakes:
x=xmin+rand(1,n)*(xmax-xmin)+(xmin + rand(1,n)*(xmax-xmin))*1i
You should add xmin to the sum and change - to * in the second part.
I've added some spaces to your code so the difference more obvious:
x = xmin+rand(1,n)*(xmax-xmin) + ( rand(1,n)-(xmax-xmin) )*1i
^^^ correct ^^^ not correct: missing `xmin+`
(and as OmG noted, also a `-` instead of a `*`)
One good way to reduce the number of bugs is by avoiding code duplication. You could for example write:
rand_sequence = #(m,xmin,xmax) xmin+rand(1,n)*(xmax-xmin);
x = rand_sequence(n,xmin,xmax) + 1i*rand_sequence(n,xmin,xmax)
(This looks like more code, but the more complicated code logic is not duplicated.)
Or like this:
x = xmin + (rand(1,n)+1i*rand(1,n)) * (xmax-xmin);

Rounding to two decimal places is not working

I am trying to reduce the decimal places of my number to two. Unfortunately is not possible. For this reason I added some of my code, maybe you will see the mistake...
Update [dbo].[company$Line] SET
Amount = ROUND((SELECT RAND(1) * Amount),2),
...
SELECT * FROM [dbo].[company$Line]
Amount in db which I want to change:
0.00000000000000000000
1914.65000000000010000000
376.81999999999999000000
289.23000000000002000000
Result I get after executing the code:
0.00000000000000000000
1366.28000000000000000000
268.89999999999998000000
206.38999999999999000000
Result I want to get (or something like this):
0.00000000000000000000 or 0.00
1366.30000000000000000000 or 1366.30
268.99000000000000000000 or 268.99
206.49000000000000000000 or 206.49
RAND() returns float.
According to data type precedence the result of multiplying decimal and float is float, try:
ROUND(CAST(RAND(1) as decimal(28,12)) * Amount, 2)
this should do the trick.

arc4random throwing out huge numbers

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?

How to get Exponent of Scientific Notation in Matlab

When the numbers are really small, Matlab automatically shows them formatted in Scientific Notation.
Example:
A = rand(3) / 10000000000000000;
A =
1.0e-016 *
0.6340 0.1077 0.6477
0.3012 0.7984 0.0551
0.5830 0.8751 0.9386
Is there some in-built function which returns the exponent? Something like: getExponent(A) = -16?
I know this is sort of a stupid question, but I need to check hundreds of matrices and I can't seem to figure it out.
Thank you for your help.
Basic math can tell you that:
floor(log10(N))
The log base 10 of a number tells you approximately how many digits before the decimal are in that number.
For instance, 99987123459823754 is 9.998E+016
log10(99987123459823754) is 16.9999441, the floor of which is 16 - which can basically tell you "the exponent in scientific notation is 16, very close to being 17".
Floor always rounds down, so you don't need to worry about small exponents:
0.000000000003754 = 3.754E-012
log10(0.000000000003754) = -11.425
floor(log10(0.000000000003754)) = -12
You can use log10(A). The exponent used to print out will be the largest magnitude exponent in A. If you only care about small numbers (< 1), you can use
min(floor(log10(A)))
but if it is possible for them to be large too, you'd want something like:
a = log10(A);
[v i] = max(ceil(abs(a)));
exponent = v * sign(a(i));
this finds the maximum absolute exponent, and returns that. So if A = [1e-6 1e20], it will return 20.
I'm actually not sure quite how Matlab decides what exponent to use when printing out. Obviously, if A is close to 1 (e.g. A = [100, 203]) then it won't use an exponent at all but this solution will return 2. You'd have to play around with it a bit to work out exactly what the rules for printing matrices are.

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.