int and ++new goes up by 2 every time - iphone

Just a silly question:
I have a simple counter, but it seems that it gives the double value of what I expect.
short int *new = 0;
++new;
NSLog(#"Items: %hi", new);
And this returns:
Items: 2
Relatively new to Cocoa, and still working out the little details as is clear form above...

You don't have an integer variable, you have a pointer to an integer variable (a short integer, to be specific). It increments by 2 because short integers are two bytes long. A pointer variable holds a memory address of another value. Incrementing a pointer means, "make this pointer point to the next thing in memory", where "thing" is the type of value the pointer was declared to point at. A pointer to double would increment by 8 each time.
The "*" in the declaration makes it a pointer. If you just want an int, you'd just write
short int new = 0;
++new;

Aah, when you increment a pointer, in increments it by the size of the object it holds. You're looking at an address, not a number.
do this, and see:
short int *new = 0;
NSLog(#"Items now: %hi", new);
++new;
NSLog(#"Items then: %hi", new);

Because the way you define new is as a pointer to an integer, *new. You set the memory location to contain a short int, which is a 16-bit integer, so it takes up two bytes in memory. So increasing that on the second line means increasing the memory location by 2.
I don't think you intend to deal with memory locations. It's kind of odd to define an integer and also control its location in memory, unless in specific situations. Code that would do what you want is:
short int new = 0;
++new;
NSLog(#"Items: %hi", new);

Related

Assigning a value to the pointer to an object

class Distance
{
public:
int a;
};
int main()
{
Distance d1; //declaring object
char *p=(char *)&d1;
*p=1;
printf("\n %d ",d1.a);
return 0;
}
This is my code.
When I am passing the value of 'a' to be like 256,512 , I am getting 257,513 respectively but for values like 1000 i get 769 and for values like 16,128,100 I am getting 1.
First I thought it might be related to powers of 2 being incremented by 1 due to changes in their binary representation. But adding 1 to binary representation of 1000 won't give me 769.
Please help me to understand this code.
*p = 1 sets the last byte(char) to 000000001
As you're type casting int to char,
binary for (int)1000 is (binary)0000001111101000
you're assigning (int)1 for last 8 bits i,e (binary)0000001100000001 which is 769.
Using 256512 worked because last 8 bit that you change are all zeros i.e (int)256512 is (binary)111110101000000000 so making last bit as 1 gives you (binary)111110101000000001 which is (int)256513
And I think(not sure) you get 1 for 16,128,100 because this integer is well out of int range and thus not assigned and a is set to 0 as class object is created. and thus setting last bit to 1 makes a = 1

NSNumber, what to be aware of when using and storing different primitive types

An NSNumber can store different primitive types, like short, int, long, long long, float, double
But does the size change, when i do
#(long long)
in comparison to
#(int)
By modeling the CoreData model, i use Integer16, Integer32, Integer64, but does it have an outcome on the size of the database, as all is NSNumber?
To a CoreData property, which has in model defined Integer16
long long tmp = 83324;
NSNumber * numberStoringLongLong = #(tmp);
cdEntity.propertyInteger16 = numberStoringLongLong;
long long tmp2 = [cdEntity.propertyInteger16 longLongValue];
Would propertyInteger16 behave right? Would tmp2 be valid?
Your first example will not work as intended. Even if NSNumber can store short, int, long and long long, Core Data dynamically creates custom accessors for the properties that
depend on how you defined the type in the Core Data Model.
A quick test with "Integer 16/32/64" attributes shows that behaviour:
NSNumber *n = #(0x11223344556677);
[cdEntity setValue:n forKey:#"i16"];
[cdEntity setValue:n forKey:#"i32"];
[cdEntity setValue:n forKey:#"i64"];
NSLog(#"%#", cdEntity);
Output:
<NSManagedObject: 0x7491030> (entity: Entity; id: 0x7491090 <x-coredata:///Entity/t4521AA03-435E-4683-9EAF-ED6EED5A5E6A2> ; data: {
i16 = 26231;
i32 = 1146447479;
i64 = 4822678189205111;
})
As you can see, storing an integer attribute that does not fit into the declared size
of the property does (silently) truncate the value.
So in your example, storing 83324 = 0x1457C in an Integer 16 attribute will
truncate that value to 17788 = 0x457C, and that is what you will get back, even if you
use longLongValue.
It shouldn't make a difference. As I understand it, when you allocate an NSNumber, it reserves a specific amount of memory as required in order to represent itself. When you make changes to the value of an NSNumber it should still be taking up the same amount of size in the database regardless of what actual value it's holding (same way an int is still an int whether it's set to 1 or 2147483647).
I'm too lazy to check, but if you're in xcode under openDeveloperTools>instruments there's an allocations tool and a leaks tool. You could run a for-loop and intentionally leak #(int) values, then #(longlong) values and see if there's a difference in how fast it consumes heap.

int++ increments by 4

Here's my code:
- (IBAction)NextTouched:(id)sender {
NSLog(#"Index = %i", index);
if([project getCount]>(index++)) {
[self setUI:index];
}
}
Index is an integer, as declared in my .h file:
#property (nonatomic) int *index;
But every time I click the button, the log says the integer is going up by 4. Can you tell my why?
The reason it's going up by 4 is because index is a pointer. When you increment a pointer its value increases by the size of the data type it points to, in this case an int, which is 4 bytes.
Given index appears to be an index into an NSArray (or some other collection class), I think you want to make it int and not int * to solve your issue. Better still make it unsigned, like NSUInteger, which is the type returned from the count method.
Also I think you'll want to use prefix-increment rather than postfix-increment so that the if test uses the newly incremented value, not the previous value.
Simply define index as an integer variable rather than pointer and if you want to print the value before increment use index++ else use ++index to increment the value and then print

float arrays in objective C

Do I need to null-terminate a basic float array in objective C?
I have a basic float array:
float data[] = {0.5, 0.1, 1};
and when I do a sizeof(data) I get "12".
You don't need to null terminate it to create one, no. And in general a method taking a float[] would also take a size parameter to indicate how many elements there are.
You get sizeof(data) = 12 because a float is 4-bytes on your architecture and there's 3 of them.
sizeof return the amount of memory (in bytes) occupied by the parameter. In your case, every float occupies 4 bytes, thus 4*3=12.
As Hot Licks said in the comment of mattjgalloway's answer, there is not a standard way to retrieve the number of elements in a C array.
Using size = sizeof(data) / sizeof(float) works, but you must be careful in using this approach, since if you pass the array as a parameter it won't work.
A common approach is to store the size in a variable and use it as upper bound in your for loop (often functions that expect an array have an additional parameter to get the size of the array).
Using a null-terminated array is useful because you can iterate through your array and stop when the i-esim element is null (that's the approach of methods like strcmp).
Values of type float can never be null, so it's not possible to terminate an array of type float with null. For one thing, variables of any primitive type always have a numeric value, and the various null constants (in Objective-C nil, Nil, NULL, and '\0') have the literal value 0, which is obviously a valid value in range of a float.
So even if you can compile the following line without a warning,
float x = NULL;
...it would have the same consequence as this:
float x = 0;
Inserting a null constant in an array of type float would be indistinguishable from inserting 0.0 or any other constant zero value.

What's the largest variable value in iphone?

I need to assign 2,554,416,000 to a variable. What would be the primitive to use, and what would be the object representation class to use? Thanks.
Chuck is right, but in answer to the "object representation", you want NSNumber used with the unsignedInt methods.
NSNumber *myNum = [NSNumber numberWithUnsignedInt:2554416000];
NSUInteger myInt = [myNum unsignedIntValue];
2,554,416,000 = 0x9841,4B80 ≤ 0xFFFF,FFFF (UINT_MAX), so uint32_t (unsigned int) or int64_t (long long).
A signed int32_t (int) cannot represent this because 0x9841,4B80 > 0x7FFF,FFFF (INT_MAX). Storing it in an int will make it negative.
This can be represented by a 32-bit unsigned integer (UINT_MAX is about 4 billion). That's actually what NSUInteger is on the iPhone, but if you want to be very specific about the bit width, you could specify a uint32_t.
You could store it in a regular int scaled down by 1000 if you wanted, if this represented a score that could never have the bottom 3 digits hold any info or something similiar. This would be a way to save a few bits and possibly an entire extra int of space, if that matters.