How can i convert CGFloat to an Integer Value (iPhone SDK) - iphone-sdk-3.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.

Related

Objective-C: Type casting object to integer_t

integer_t is a typedef of int32_t as defined here, and after some checking, integer_t has a size of 4 bytes, and so does int (intValue) as per mentioned is this doc. My question is, is casting like this produce valid result?
integer_t value = 100;
id anObject = #(value);
integer_t aValue = [anObject intValue];
Is aValue always equal to value? Will this cause any issue in the long run? Should I do long value = [anObject longValue] instead? Thanks in advance.
Short and specific answer - YES those values are equal since integer_t and int both (according to you - here's the catch) have the same size AND the same signedness. If one was e.g. some type of unsigned int then it would not work. Neither would it work if one was e.g. 8 bytes (long) and the other 4 (int).
The long and general answer is - it depends. Yes, here you think it is equal but there are always funny cases you need to watch out for. I already mentioned the size and signedness but the real trip can be over the system architecture. So you might assume they are the same and then one day you compile for 64b arch and all breaks down as int there has 8 bytes length and integer_t still is 4 e.g. You could also run into endianness troubles. Thus if you get a bunch of ints from a mainframe they could be stored BADC where A, B, C and D are the 4 bytes of the int.
As you can see, it is easy to scare anybody working with these, and in practice that is why there are things such as NSInteger - Objective-C's attempt to protect you from these. But don't be scared, these are toothless monsters, unless you work at a low level, and then your work will be to work with them. Doesn't that sound poetic.
Back to the code - don't worry too much about these. If you work in Objective-C, maybe try to use the NSInteger and NSUInteger types for now. If you store these and need to load it again later then you need to think about the possibility that you store it from a 32b arch and restore it on a 64b arch and work around that somehow.

What is the meaning of "float *newAudio"

Sorry for my newbie question. Please refrain from down voting me because I am learning C. I am an experienced programmer on other languages, but not on C. I am trying to learn C at the same time I am trying to understand a library for iOS called Novaine, on Github.
This library has a module with the following signature:
Novocaine *audioManager = [Novocaine audioManager];
[audioManager setInputBlock:^(float *newAudio, UInt32 numSamples, UInt32 numChannels) {
}];
So, the internal block is receiving numSamples, numChannels and newAudio and newAudio is of kind float pointer?
What kind of object is this? an array of floats? if this is an array, how do I access its values? How do I know the number of elements it has?
This is a pointer to float value. Nothing strange here. It is often use to point some area in memory. You don't know the size of this are. Might be a single float but also can be larger, continuous space in memory.
You don't know what type of object is stored there. float doesn't mean that floats are stored there. It could be declared as void * as well. Again, it is just a space in memory. By typing float * you just give the compile a hint that when you move newAudio pointer (doing or example newAudio ++) it will move a pointer by a sizeof(float) number of bytes.
Based on method fingerprint I assume that this is a pointer to the first element of some buffer which size is probably numSamples * numChannels * size of single sample
This part of memory should be allocated first, to make sure that it's reserved for you:
float *newAudio = calloc(numSamples * numChannels, sizeof(float));

Need a more performant way of storing a large amount of floats into an array and reading them back

In my app I have to store path points into an array and then follow those points. To get a smoother run I usually have to dump a path into 5k points. This means I have to store 10k floats- 5k for x and 5k for y coordinates. Right now this is what I'm doing:
1.In the view load I initialize an NSArray with those 10k numbers like this:
pathPoints=[NSArray arrayWithObjects:[NSNumber numberWithFloat:-134.8427], [NSNumber numberWithFloat:148.8433], ....... and so on];
And then I read it like this:
int currentXIndex=..////
[[pathPoints objectAtIndex:currentXIndex] floatValue];
[[pathPoints objectAtIndex:currentXIndex+1] floatValue];
As you can see, each time when I need the next position? I have to unbox it(cast it from NSNumber to float). And I'm sure this takes a great deal of performance. Any suggestions how I can do this another, more performant way?
For a simple container, I'd use a C array and traverse with pointers. Remember that Objective C is a superset of C, so you have everything right there for when the need arise.
edit; sample code:
you don't have to store all numbers 'naked', a struct don't have any overhead:
typedef struct tCoords {
float x, y;
} tCoords;
then just malloc() the size needed:
arraySize = 5000;
tCoords *array = malloc(arraySize * sizeof(tCoords));
and iterate like any simple array:
tCoords *end = array+arraySize;
for (tCoords *p = array; p<end; ++p) {
float x = p->x;
float y = p->y;
}
If you don't like the "old C" look of the code, it's easy to encapsulate all this in a class that 'owns' the array (don't forget to free() it when disposed)
Use a plain array instead of NSArray?
float *pathPoints;
pathPoints = new float[10000];
...
...
delete [] pathPoints;
Or for a constant array
float pathPoints [] = {-134.8427,148.8433, ... and so on};
You can reduce in half the amount of wrapping reasonably cheaply by using [NSValue valueWithPOint:(CGPoint...)] method to box a pair of coordinates as one id object instead of two. This should also reduce the memory required to store the pairs.
If this is not enough, you could "bundle" more elements together in a single wrapper. For example, if you know that your paths are created in groups of, say, 32 points, you can store arrays of 32 CGPoint objects wrapped in NSData (use [NSData dataWithBytes:.. length:..] method). When you need a point at index i, grab a group at index i/32 from NSArray, unwrap from NSData, and then take element at i%32.
If everything else fails, make a class to represent an array of CGPoint structures by hiding calls of malloc and free behind a nice-looking Objective C interface.
you could use a C array of floats...
for info on C arrays:
Resizing an array with C

Could you help me understand Pointers please?

I know this has been asked previously but one thing that these other questions didn't touch upon is why
Allow me to explain. I just ran through a tutorial that outputted integers and pointers to show you how to do it.
int anInteger = 50;
int *anIntPointer = &anInteger;
So, to set up a pointer I assign a variable value as normal, and then I assign that variable to a pointer. This I understand, but as I've already said, this is the how not the why.
If I wanted to return the value 50 I could just NSLog anInteger so why would I need a pointer. Why would I need to NSLog *anIntPointer if I could just NSLog anInteger which does exactly the same thing?
Okay, I know this is very trivial and there are probably perfect circumstances to use a pointer, but so far no tutorial that I've read or watched will give me a perfect circumstance. They all deal with the how
Please help me find the why.
Pointers have many uses. One obvious one is that you want to call a function and have it modify one of your variables:
void f(int *i) { *i = 42; }
int g() { int i; f(&i); return i; }
Another is to return a large struct without a huge amount of copying:
struct big_struct *f() {
big_struct *bs = malloc(sizeof(big_struct));
// Populate the big_struct;
return bs;
}
Yet another is to manage arrays who's size you don't know at compile:
struct item *fetch_items(int n) {
item *i = malloc(n*sizeof(item));
load_items(i, n);
return i;
}
Still another is recursive data types, such as linked lists:
struct node {
int value;
struct node *next;
};
And this is just a sampling. Pointers are like nails to a carpenter. They are a key tool in almost any non-trivial programming problem.
The main reasons why we use pointers (in C and C-derived languages) are:
To mimic pass-by-reference semantics
To track dynamically-allocated memory
To create self-referential and dynamic data structures
Because sometimes the language forces you to
To mimic pass-by-reference semantics: In C, all function arguments are passed by value. The formal parameters and the actual parameters are different objects in memory, so writing to the formal parameter has no effect on the actual parameter. For example, given the code
void swap(int a, int b)
{
int tmp = a; a = b; b = tmp;
}
int main(void)
{
int x = 2, y = 3;
printf("before swap: x = %d, y = %d\n", x, y);
swap(x, y);
printf("after swap: x = %d, y = %d\n", x, y);
return 0;
}
a and x are physically distinct objects; writing to a does not affect x or vice versa. Thus, the before and after output in the program above will be the same. In order for swap to modify the contents of x and y, we must pass pointers to those objects and dereference the pointers in the function:
void swap(int *a, int *b)
{
int tmp = *a; *a = *b; *b = tmp;
}
int main(void)
{
int x = 2, y = 3;
printf("before swap: x = %d, y = %d\n", x, y);
swap(&x, &y);
printf("after swap: x = %d, y = %d\n", x, y);
return 0;
}
a and x are still distinct objects in memory, but the expression *a refers to the same memory as the expression x; thus, writing to *a updates the contents of x and vice versa. Now the swap function will exchange the contents of x and y.
Note that C++ introduced the concept of a reference, which sort of acts like a pointer but doesn't require an explicit dereference:
void swap(int &a, int &b)
{
int tmp = a; a = b; b = tmp;
}
int main(void)
{
int x = 2, y = 3;
std::cout << "before swap: x = " << x << ", y = " << y << std::endl;
swap(x, y);
std::cout << "after swap: x = " << x << ", y = " << y << std::endl;
return 0;
}
In this case, the expressions a and x do refer to the same memory location; writing to one does affect the other. This is a C++-ism, though.
I'm not familiar enough with Obj-C to know if they have a similar mechanism.
To track dynamically-allocated memory: The C memory allocation functions malloc, calloc, and realloc, along with the C++ operator new all return pointers to dynamically allocated memory. If you have to allocate memory on the fly, you have to use pointers to refer to it. Again, I'm not familiar enough with Obj-C to know if they use a different memory allocation mechanism.
To create self-referential and dynamic data structures: Aggregate types such as struct or union types cannot contain an instance of themselves; for example, you can't do something like
struct node
{
int value;
struct node next;
};
to create a linked list node. struct node is not a complete type until the closing }, and you cannot declare objects of an incomplete type. However, a struct can contain a pointer to an instance of itself:
struct node
{
int value;
struct node *next;
};
You can declare a pointer to an incomplete type, so this works. Each node in the list can refer to the node immediately following it. And since you're dealing with pointers, you can add or delete nodes from the list reasonably easily; you just have to update the pointer values, instead of physically moving data around.
I can pretty much guarantee that any container type in Obj-C uses pointer manipulation under the hood.
Because sometimes the language forces you to: In C and C++, an expression of array type will implicitly be converted to a pointer type in most circumstances. Array subscripting is done in terms of pointer arithmetic; the expression a[i] is evaluated as though it were written *(a + i). IOW, you find the address of the i'th element after a and dereference it.
Pointers are not specific to Objective-C, in fact they are used in C and [usually not so much C++]. Basically, it is how you pass objects by reference.
void thisFunctionModifiesItsArgs(int *x, int *y, int *z)
{
*x = 4;
*y = *z;
*z = 100;
}
int main()
{
int a = 0;
int b = 1;
int c = 2;
thisFunctionModifiesItsArgs(&a, &b, &c);
// now, a = 4, b = 2, and c = 100
}
the most obvious reasons:
1) you want the object pointed to to live beyond the scope of its use, so you create an allocation. accessing the int's address beyond its scope is asking for trouble -- the address is likely used by something else at that point. if you create a unique memory location for it, that problem is solved (or... maybe displaced).
2) you want to pass it by reference/pointer/address. this is useful to mutate an object, or as an optimization when the type is large.
3) support for polymorphism and/or opaque types
4) pointer to implementation (abstraction, dependency reduction)
and on... (i wouldn't expect you to understand all those cases at this stage)
so, the example you show is so trivial that it does not represent (any of) those cases -- it only attempts to introduce the syntax.
there are many cases, and they are used regularly in real world C, C++, ObjC, etc. programs for many different reasons.
A simple answer: because there are variables that are more complex than simple integers. The tutorial is giving you a very simple case to explain the concept, but the simple case they describe would almost never be used.
Justin's answer is spot on for what you're asking. If you need a good tutorial then I recommend chapter 5 of "Beginning Mac Programming" which explains how the memory addressing works and how this is essential for working with pointers, and the reasons why.
Computer Science 001
Computers (the computer chip) can only do three things, but they can do them million or even billions of times per second.
They can store information (a number) into memory.
They can do arthimetic on those numbers.
They can make simple decsions based on the arthimetic, like if a = b then go to address X.
Thats it.
A very simple analogy I use to explain pointers to beginners in assembler programming is to think of memory like a row of mailboxes. The first mailbox has address 0 and the next is one plus and so forth.
When a computer starts up, it is told to go to mailbox 0 and get the content.
The content can be information or a command, mailbox 0 always holds a command. The command might be Go to mailbox 1 and get its content.
The content of a mailbox can only hold so much information, just like a real mailbox can only hold so much information. If the postman need to deliver a package for example, he will put a notice in the mailbox to go to the post office to pick it up. The notice is like a pointer. The pointer does not hold the information, the real information is located where the pointer says it is located, in this case the post office.
You could even get to the post office to find out there is nothing but another pointer to another location. We would call that a "handle" or a pointer to a pointer.
If you want to copy a byte sequence from one place to other place, (naturally) you have to know the source and destination addresses. To express it in the language's abstraction level, you can use pointers, which represents the memory locations.
Beside notes has been written already, in lower levels, pointers are very often used. A very simple example: Writing to the 80x25 screen. For example the base address of the screen is 0xb8000, where the first character of the screen is stored. You can use pointers, with wich you can write a character to the appropriate position in the screen. e.g. : unsigned short* sc = (unsigned short*)0xb8000; *sc = 'A' | (attr) << 8; . And so on...
N.B.: Pointers embodies indirection, and it is possible, you can have "multiple" pointers: ** (imagine the C main functions signature, and the char** in it!). Or e.g. you want to create a list structure with malloc in a separate function. Then you can pass a struct list** or what have you parameter and in the function you can assign a value (a memory address) to the list, which means you have created the list in the memory.

Add integers from 5 UITextFields to a UILabel in Cocoa Touch

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.