I'm new to Xcode development, and i would like to know how can i generate random numbers from 2 inputs.
In IB i have 2 textfields (with Number pad) that indicate the interval of the numbers to generate (i.e. from 3 to 7). I would like to know how i get the inputs from the 2 textfields and do a method that generate random numbers from these inputs.
There are many issues involved in trying to generate a truly random number. Note, for instance, that functions like rand() and random() generate sequences of numbers based on a 'seed value'. That means that if the seed value is the same, the sequence of numbers generated will be the same. There are various ways to use 'random' seeds - ie., using the current date and time - but the reliability and security of these methods is questionable.
As the number generators evolve, these issues get addressed, and therefore the later generators are usually better than the earlier ones: rand is generally not as random as random, and random is not as random as arc4random.
The current problem with arc4random(), which is documented in their manual pages, is that using a modulus calculation - as in "arc4random() % UPPER_LIMIT" - can introduce statistical bias, if UPPER_LIMIT is not an even number. Because of this, a new function was added to the arc4random family, called arc4random_uniform. It produces evenly distributed random numbers, regardless of the upper limit - and it is quite simple to use.
Using your example above, I would recommend you try generating your random number like this:
int value = low_bound + arc4random_uniform(width + 1);
int low_bound = 3;
int high_bound = 7;
int width = high_bound - low_bound; // 4
int value = low_bound + arc4random() % (width + 1); // 3 + 0..4
Plus read the bounds from the fields, something like bound = [[field text] intValue].
If you have trouble connecting the input fields to the code, you should read some Cocoa tutorial. There are several ways to do it, one of the most straightforward is declaring properties for the text fields in the controller class:
#interface Controller : UIViewController {}
#property(retain) IBOutlet UITextField *lowerBoundField;
#property(retain) IBOutlet UITextField *upperBoundField;
#end
Then you can connect the text fields in the Interface Builder to these outlets and work with them in code like this:
- (void) generateNumber {
int lowerBound = [[lowerBoundField text] intValue];
…
}
This is assuming we are talking about Cocoa Touch. In desktop Cocoa the situation is similar, just the details would be different.
Related
Here's what I'm looking to do:
I have a series of survey questions that are generated randomly for the user.
What I want is to associate two values with each other, the integer value of the question number that was generated randomly, and a integer value representative of how many times this user has answered this question. I want to be able to save and retrieve these associated values later so I can increment how many times the user has answered this question.
So, how do you associate two different integer values to each other, save, and update them later?
I'm starting with this code.
QuestionSelected = arc4random_uniform(4);
For example once this outcome was generated:
QuestionSelected = 1
I would need to establish a new value that I can associate with that question's value (1), increment it, and then save each time the user returns to this question.
Thanks for your help!
Association of one value with another is a "map". NSDictionary is the standard mapping collection in Cocoa, so you can use that:
NSNumber * timesSeen = myMutableDictionary[#(selectedQuestion)];
if( !timesSeen ){
timesSeen = #(0);
}
myMutableDictionary[#(selectedQuestion)] = #([timesSeen intValue] + 1);
Since an array in essence associates its indexes, which are numbers, with values, another option is to use an NSMutableArray:
NSNumber * timesSeen = myMutableArray[selectedQuestion];
myMutableArray[selectedQuestion] = #([timesSeen intValue] + 1);
An NSArray can't be sparse, so you would have to fill it up with zeroes when you create it:
for( NSUInteger i = 0; i < numQuestions; i++ ){
[myMutableArray addObject:#(0)];
}
As you may notice, dealing with numerical values that need to change in a Cocoa collection is a bit of a pain, because the NSNumbers have to be unboxed and replaced each time. So a third option would be a C array:
int * viewCounts;
viewCounts = calloc(numQuestions, sizeof(int));
viewCounts[selectedQuestion]++;
calloc() gets a chunk of memory for you and fills it with zeros. You will need to release that memory by calling free(viewCounts) when you are done with the array.
I am reading "Programming in Objective-C" 4th Ed. by Stephen G. Kochan. In the book, there is a sample code for creating a Calculator application for the iPhone. I understand the code, at least 90% of it. - There is a Fraction class that has methods to store fraction objects and that describe how to perform different basic fraction arithmetic operations
- In addition to that, there is a calculator class that runs the appropriate methods from the Fraction class depending on whether the user is trying to sum, divide etc.
The view controller has the following method for when the user presses a number in the interface:
-(IBAction)clickDigit:(UIButton *)sender {
int digit = sender.tag; //sender or the argument inthis case is the button
[self processDigit:digit];
}
As you see this method is now called:
-(void) processDigit:(int)digit {
currentNumber = currentNumber * 10 + digit;
[displayString appendString:
[NSString stringWithFormat:#"%i", digit]];
display.text = displayString;
}
My ONLY question (and probably the one with the most simple answer) is: Why is currentNumber always multiplied by 10? The value of currentNumber is always 0 by the time the compiler enters the method above (I verified this using the debugger in XCode) so i dont get why we even have to multiply it by 10. I did delete that multiplication and the results are incorrect, i just cannot figure out why yet.
Thank you
Maybe the best way to think about this is with an example.
Imagine the user has clicked the following digits in order: 1, 2. Then, assuming the code is working, the numeric value of currentNumber should be 12.
Now imagine the user next clicks on '3'. Now you want the value to be 123. You can get this by multiplying the previous value (12) by 10 and then adding the 3. If they then click on a '4', the value should become 1,234, which is achieved by 10 * 123 + 4. And so on.
Imagine your calculator has "123" on the screen and you want to turn this into "1234". If it was a string you can add "4" to the end, and it works fine. But it's an integer, and if you add 4 to the integer value you get 127. So what you do is take 123, multiply by 10 to give you 1230, then add the 4 to get 1234.
The debugger must be misleading you, as it sometimes does.
Consider that if taking the multiplication out makes the result wrong then the multiplication obviously does something!
Try the following for debugging only:
int lastCurrentNumber = currentNumber;
currentNumber = 10 * lastCurrentNumber + digit;
Now in the debugger check the values of lastCurrentNumber, currentNumber and digit as you step through these two statements.
The *10 is used to move digits through the various places in decimal numbers (tens place, hundreds place, etc.)
It's kind of a "hack" to avoid having to use an array. Other calculator apps "pop" and "push" digits onto an array, this allows for more powerful operations as well as manipulation of non-decimal numbers (binary, hex, etc.)
The free iOS development course on iTunes U includes a calculator app that uses an array. If you'd like to compare the difference, you can download the source code here:
http://www.stanford.edu/class/cs193p/cgi-bin/drupal/
It also has a Fraction object but doesn't use the *10 method.
I'm trying to sum the integers from five UITextFields and post them to a UILabel.
This is the code I have tried, but it doesn't work properly. The number that shows up in the label is not the sum of my textfields. I have also tried to post to a textfield instead of a label, with the same result. No errors or warnings when I build.
int val = [textfield1.text intValue]
val = val+[textfield2.text intValue];
val = val+[textfield3.text intValue];
val = val+[textfield4.text intValue];
val = val+[textfield5.text intValue];
NSString *labelStr = [[NSString alloc] initWithFormat:#"%i", val];
label.text = labelStr;
Something wrong with the code? Alternative code? Grateful for all answers!
The code looks more or less right to me, aside from the memory leak. You should review the memory management rules and fix your leak.
My guess is that the numbers you entered add up to a number that is outside the range of an int. Entering, say, 1000000000 (10**9) in each of the five fields would be one way to pull this off, on any machine where an int is 32 bits (including, currently, the iPhone-OS devices).
Depending on the purpose of your app, you may be able to simply cap the five input fields; if the highest value that makes any sense is less than one-fifth (for five fields, and that's assuming they all have the same cap) of the maximum int, overflow is impossible.
If a cap won't solve the problem completely, try a different type. If the values should never be negative, use an unsigned type. Otherwise, try long long, or either of the floating-point types, or use NSDecimalNumber objects.
Of course, I could be completely wrong, since you didn't say what numbers you entered or what the result was. If it was zero, make sure that you hooked up your outlets in IB; if you forgot to do that, they contain nil, which, when you ask it for text, will return nil, which, when you ask it for an intValue, will return 0, and 0 + 0 + 0 + 0 + 0 = 0.
My problem is: I'm trying to convert my CGFloat Values to an integer value and than add them to an NSMutableArray.
For Example;
CGFloat x=ship.center.x
//convert x to integer
?
P.S.:After that, I will send these values to another iPhone with bluetooth. But first I must solve this problem. İf anyone knows how to send an array data to another iPhone with bluetooth, it also works :)
Firstly, why do you want to convert to int? CGfloat is just a typedef for float, and can be sent as-is, especially if you know that your sending iPhone to iPhone, since they will use the same memory representation for floats. If you still need to do this for some reason...
// Choose constants m and c so that the resulting integers
// span as much of the range (INT_MIN, INT_MAX) as possible,
// thus minimising aliasing effects. Also consider using
// long long (64-bit integers).
int x = (int)(m*ship.center.x+c)
NSMutableArray only stores objects, so you might want to use a simple array instead:
int* arr = malloc(sizeof(x)*ships.length);
for (int i = 0; i < ships.length; i++) {
arr[i] = (int)ships[i].center.x;
}
send_data(arr, sizeof(x)*ships.length);
I've never programmed with a Bluetooth stack, so I can't help you there. Sorry.
I'm still learning, and I'm just stuck. I want the user to enter any number and in result, my program will do this equation:
x = 5*y
(y is the number the user adds, x is outcome)
How would I do this? I'm not sure if I'm suppose to add in an int or NSString. Which should I use, and should I enter anything in the header files?
I'm not sure if I'm suppose to add in an int or NSString.
Well, one of these is a numeric type and the other is a text type. How do you multiply text? (Aside from repeating it.)
You need a numeric type.
I would caution against int, since it can only hold integers. The user wouldn't be able to enter “0.5” and get 2.5; when you converted the “0.5” to an int, the fractional part would get lopped off, leaving only the integral part, which is 0. Then you'd multiply 5 by 0, and the result you return to the user would be 0.
Use double. That's a floating-point type; as such, it can hold fractional values.
… should I enter anything in the header files?
Yes, but what you enter depends on whether you want to use Bindings or not (assuming that you really are talking about Cocoa and not Cocoa Touch).
Without Bindings, declare an outlet to the text field you're going to retrieve the multiplier from, and another to the text field you're going to put the product into. Send the input text field a doubleValue message to get the multiplier, and send the output text field a setDoubleValue: message with the product.
With Bindings, declare two instance variables holding double values—again, one for the multiplier and one for the product—along with properties exposing the instance variables, then synthesize the properties, and, finally, bind the text fields' value bindings to those properties.
If you're retrieving the NSString from a UI, then it's pretty simple to do:
NSString * answer = [NSString stringWithFormat:#"%d", [userInputString integerValue]*5];
This can be done without any objective C. That is, since Objective-C is a superset of C, the problem can be solved in pure C.
#include <stdio.h>
int main(void)
{
int i;
fscanf(stdin, "%d", &i);
printf("%d\n", i * 5);
}
In the above the fscanf takes care of converting the character(s) read on the standard input to a number and storing it in i.
However, if you had characters from some other source in a char* and needed to convert them to an int, you could create an NSString* with the – initWithCString:encoding: and then use its intValue method, but in this particular problem that simply isn't needed.