Different results for the same function - iphone

Can someone clarify to me please why past2 is NOT negative when this code is run? Even though past is.
Thanks.
NSTimeInterval p1 = (arc4random()%600000);
NSTimeInterval past = -p1;
NSTimeInterval past2 = -(arc4random()%600000);

arc4random() returns an unsigned int (u_int32_t), so trying to make it negative is coercing the result to unsigned as well, which is why you're getting a very large positive number instead of a negative number.
If you want to get a negative random result in one call, try:
NSTimeInterval past2 = - (int) (arc4random()%600000);
joe

Related

How to convert NSTimeInterval to int?

How do I convert NSTimeInterval into an Integer value?
My TimeInterval holds the value 83.01837. I need to convert it into 83. I have googled but couldn't find any help.
Direct assignment:
NSTimeInterval interval = 1002343.5432542;
NSInteger time = interval;
//time is now equal to 1002343
NSTimeInterval is a double, so if you assign it directly to a NSInteger (or int, if you wish) it'll work. This will cut off the time to the nearest second.
If you wish to round to the nearest second (rather than have it cut off) you can use round before you make the assignment:
NSTimeInterval interval = 1002343.5432542;
NSInteger time = round(interval);
//time is now equal to 1002344
According to the documentation, NSTimeInterval is just a double:
typedef double NSTimeInterval;
You can cast this to an int:
seconds = (int) myTimeInterval;
Watch out for overflows, though!
In Swift 3.0
let timestamp = round(NSDate().timeIntervalSince1970)
I suspect that NSTimeInterval values from NSDate would overflow an NSInteger. You'd likely want a long long. (64 bit integer.) Those can store honking-big integer values (-2^63 to 2^63 -1)
long long integerSeconds = round([NSDate timeIntervalSinceReferenceDate]);
EDIT:
It looks like an NSInteger CAN store an NSTimeInterval, at least for the next couple of decades. The current date's timeIntervalSinceReferenceDate is about 519,600,000, or about 2^28. On a 32 bit device, and NSInteger can hold a value from -2^31 to 2^31-1. (2^31 is 2,147,483,648
Swift 4, Swift 5
I simply cast to Int64:
Int64(Date().timeIntervalSince1970)
I had a need to store an NSDate in a Swift Number. I used the following cast which is working great.
Double(startDateTime.timeIntervalSince1970)

NSString - Truncate everything after decimal point in a double

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];

Percentage Calculation always returns 0

I am trying to calculate the percentage of something.
It's simple maths. Here is the code.
float percentComplete = 0;
if (todaysCollection>0) {
percentComplete = ((float)todaysCollection/(float)totalCollectionAvailable)*100;
}
Here the value of todaysCollection is 1751 and totalCollectionAvailable is 4000. Both are int.
But percentComplete always shows 0. Why is this happening? Can any one Help me out.
I'm new to Objective C.
But percentComplete always shows 0
How are you displaying percentComplete? Bear in mind it's a float - if you interpret it as an int without casting it you'll get the wrong output. For example, this:
int x = 1750;
int y = 4000;
float result = 0;
if ( x > 0 ) {
result = ((float)x/(float)y)*100;
}
NSLog(#"[SW] %0.1f", result); // interpret as a float - correct
NSLog(#"[SW] %i", result); // interpret as an int without casting - WRONG!
NSLog(#"[SW] %i", (int)result); // interpret as an int with casting - correct
Outputs this:
2010-09-04 09:41:14.966 Test[6619:207] [SW] 43.8
2010-09-04 09:41:14.967 Test[6619:207] [SW] 0
2010-09-04 09:41:14.967 Test[6619:207] [SW] 43
Bear in mind that casting a floating point value to an integer type just discards the stuff after the decimal point - so in my example 43.8 renders as 43. To round the floating point value to the nearest integer use one of the rounding functions from math.h, e.g.:
#import <math.h>
... rest of code here
NSLog(#"[SW] %i", (int)round(result)); // now prints 44
Maybe try with *(float)100, sometimes that is the problem ;)
I think that your value for todaysCollection and totalCollectionAvailable is wrong. Double check for that.
Put the NSLog(#"%d", todaysCollection) right before the if statement

Divide Long Long Number as Percent

In an iphone app, I have 2 large numbers stored in NSStrings, and I want to figure out the float number that is achieved by dividing them.
Right now, I have:
unsigned long long number = [string1 longLongValue];
unsigned long long number2 = [string2 longLongValue];
float percent = number/number2;
[textField setText:[NSString stringWithFormat: #"%f%%",percent]];
(I assume I have to use "unsigned long long" instead of ints because the numbers in the NSStrings are pretty high- the first one is 309,681,754 and the second is 6,854,433,820)
However, after I do this, I always get 0% in the text field. What am I doing wrong?
Thanks for any help in advance.
You are dividing integers. That always results in an integer.
What you need to do is to cast them to floats before dividing. This should work:
float percent = (float)number / (float)number2;

Incorrect value for sum of two NSIntegers

I'm sure I'm missing something and the answer is very simple, but I can't seem to understand why this is happening. I'm trying to make an average of dates:
NSInteger runningSum =0;
NSInteger count=0;
for (EventoData *event in self.events) {
NSDate *dateFromString = [[NSDate alloc] init];
if (event.date != nil) {
dateFromString = [dateFormatter dateFromString:event.date];
runningSum += (NSInteger)[dateFromString timeIntervalSince1970];
count += 1;
}
}
if (count>0) {
NSLog(#"average is: %#",[NSDate dateWithTimeIntervalSince1970:(NSInteger)((CGFloat)runningAverage/count)]);
}
Everything seems to work OK, except for runningSum += (NSInteger)[dateFromString timeIntervalSince1970], which gives an incorrect result. If I put a breakpoint when taking the average of two equal dates (2009-10-10, for example, which is a timeInterval of 1255125600), runningSum is -1784716096, instead of the expected 2510251200.
I've tried using NSNumber and I get the same result. Can anybody point me in the right direction?
Thanks!
Antonio
Is there some reason you are fudging about with NSInteger?
[NSDate timeIntervalSince1970] returns an NSTimeInterval, which is basically a double. Clean up the code and see if that helps.
NSInteger can hold values up to the INT_MAX limit that equals 2147483647 - so your value overflows the integer types limit - remember that timeInterval is a double type.
You can try to use double type in all your calculations or use -timeIntervalSinceReferenceDate method - it returns interval since 1 January 2001 and you might avoid overflow as well.
If your events object is an array or other type that allows to get its size then you can add time interval values already divided by count - that also may help to avoid overflow:
NSTimeInterval runningSum = 0;
NSInteger count = [self.events count];
for (...){
...
runningSum += [dateFromString timeIntervalSince1970]/count;
}
NSInteger is a 32 bit signed integer on iPhone and is therefore limited to values between −2147483648 and +2147483647.
You may get the desired result by using NSUInteger which is an unsigned 32 bit integer able to contain values between 0 and +4294967295.
You should however pay attention to the number of runs through the loop so you don't wrap the values.