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.
Related
Most of the Apples implementation, I could see they use a struct to store the flag bit, why they are doing like that?. Why can't we use the BOOL to handle this instead?.
See the Apple's sample code below from tableview,
struct {
unsigned int delegateheightForHeaderInSection:1;
unsigned int dataSourceCellForRow:1;
unsigned int delegateHeightForRow:1;
unsigned int style:1;
} _tableFlags;
and internally they may be using them something similar to this,
_tableFlags.delegateheightForHeaderInSection = [delegate respondsToSelector:#selector(tableView:heightForHeaderInSection:)];
use the "_tableFlags.delegateheightForHeaderInSection" everywhere to check the whether the user has implemented this delegate method.
So instead ofhaving the struct to store the flag, can't we implement like below.
BOOL delegateheightForHeaderInSection;
use it like this,
delegateheightForHeaderInSection = [delegate respondsToSelector:#selector(tableView:heightForHeaderInSection:)];
What difference does this two approaches have?.
unsigned int delegateheightForHeaderInSection:1;
defines a bit field of length 1 in the structure (see e.g. http://en.wikipedia.org/wiki/Bit_field).
Bit fields can be used to save space. So in this case, the four members delegateheightForHeaderInSection, ..., style are stored in contiguous bits of one integer.
Note that no space is saved in this particular case. The size of _tableFlags is the size of unsigned int, which is 4. The size of four BOOL (aka unsigned char) members is also 4.
But for example, 32 bit fields of length 1 also take 4 bytes, whereas 32 BOOL members would take 32 bytes.
I have a double that I need only the value of everything before the decimal point.
Currently I am using
NSString *level = [NSString stringWithFormat:#"%.1f",doubleLevel];
but when given a value of 9.96, this returns "10". So it is rounding. I need it to return only the "9". (note - when the value is 9.95, it correctly returns the "9" value.)
Any suggestions?
Thank You.
Simply assign the float/double value to a int value.
int intValue = doubleLevel;
Cast that baby as an int.
int castedDouble = doubleLevel;
Anything after the . in the double will be truncated.
9.1239809384 --> 9
123.90454980 --> 123
No rounding, simple truncation.
If you want to keep it as a float:
CGFloat f = 9.99;
f = floorf(f);
there are quite a variety of floor and round implementations.
they have been around since UN*X, and are actually part of those low-level libraries, be they BSD, Posix, or some other variety - you should make yourself familiar with them.
there are different versions for different "depths" of floating point variables.
NSString *level = [NSString stringWithFormat:#"%d",doubleLevel];
I have an NSArray in which I would like to store double values. I defined it as follow
NSMutableArray *setOfDoubles;
I add the elements as follow
NSNumber *num;
num = [NSNumber numberWithDouble:someDouble];
[setOfDoubles addObject:num];
And I read the element as follow
num = [setOfDoubles lastObject];
[setOfDoubles removeLastObject];
doubleValueToUse = [num doubleValue];
My problem is sometimes (Not always), for example when num (as an object) is 5.1, doubleValueToUse (as a double value) is 5.099999999999996. The way I figured num (as an object) is 5.1 is that I debug and when I am hovering the mouse on top of num on the line num = [setOfDoubles lastObject]; it shows 5.1 but after doubleValue conversion it becomes the number I mentioned. Does anybody know why is this happening?
Not every number can be accurately represented using a float variable. For example, you can't precisely represent, say, 1/3 using a finite number of digits in our common decimal (base-10) system, but in ternary (base-3), it would be just 0.1. Similarly, the numbers you can write with a finite number of digits in decimal, may not necessarily have the finite number of digits in their binary representation, hence the error.
A few links on the topic if you are interested:
http://floating-point-gui.de/basic/
http://www.mathworks.com/support/tech-notes/1100/1108.html
http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html
This is normal for float values.
If you want to save initial (same) representation of float numbers in all places of your code, you can save them, for example, in NSString. When you will need float number you will just write [NSString floatValue];. But it is not effective if you have large amount of float values.
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);
I'm quite sure that this question has a very simple answer that I should have figured out by now. Since I haven't yet done so I come to you, stack overflow hive mind.
I expected the loop below to print out the numbers from 0 to 5. Instead it prints out only 0 and 4. Why does LoopNumber++ increment my NSNumber LoopNumber by 4 instead of by 1?
NSNumber *LoopNumber;
for (LoopNumber=0; LoopNumber<=5; LoopNumber++) {
NSLog(#"%d",LoopNumber);
}
If I change it to the following it works exactly as I expect. What gives?
for (int LoopNumber=0; LoopNumber<=5; LoopNumber++) {
I'm fooling around with an iPhone project in XCode 3.2.1, using SDK 3.1.2.
an NSNumber is not an integer. It is an object wrapper for a number which may be an integer.
The variable LoopNumber is actually a pointer to the location in memory where the object should be. All LoopNumber itself holds is a memory address, which on your machine is 4 bytes long. When you do LoopNumber++ you are inzoking pointer aritmatic on the pointer and it is advancing to the next memory address which is four bytes later. You can see this by doing a sizeof(LoopNumber) - that would return 4 on your system.
What you really want to do is use a regular integer like so:
NSUInteger loopNumber;
for(loopNumber = 0; loopNumber <= 5; loopNumber++) {
NSLog(#"%d",loopnumber);
}
or if you really need to use NSNumbers:
NSNumber loopNumber;
for(loopNumber = [NSNumber numberWithInt:0]; [loopNumber intValue] <= 5; loopNumber=[NSNumber numberWithInt:[loopNumber intValue]++]) {
NSLog(#"%d",loopnumber);
}
int is native type. NSNumber is a Objective-C class. Use float or int when doing real work. But to put a int into a collection you can create an NSNumber object from the int or float native type.