I'm an Objective-C developer with little C/C++ experience (and zero training), and I encountered something strange today with hard coded numeric values.
I'm sure it's a simple/stupid question, but can someone please explain why this works:
NSDate *start = [NSDate date];
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^{
NSLog(@"seconds: %f", [start timeIntervalSinceNow]);
});
// output: seconds: -1.0001
And this also works (note number of seconds has changed):
NSDate *start = [NSDate date];
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^{
NSLog(@"seconds: %f", [start timeIntervalSinceNow]);
});
// output: seconds: -2.0001
But this is executed immediately:
NSDate *start = [NSDate date];
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 4 * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^{
NSLog(@"seconds: %f", [start timeIntervalSinceNow]);
});
// output: seconds: -0.0001
However, using 4.0
instead of 4
fixes it:
NSDate *start = [NSDate date];
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 4.0 * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^{
NSLog(@"seconds: %f", [start timeIntervalSinceNow]);
});
// output: seconds: -4.0001
Why do 1 and 2 properly cast to the relevant double value, but bigger numbers (I tested 3 and 4) appear to be represented as 0
?
I'm compiling with Xcode 4.2, configured to use LLVM 3.0.
EDIT:
dispatch_time_t is defined as:
typedef uint64_t dispatch_time_t;
And dispatch_time is:
dispatch_time_t dispatch_time(dispatch_time_t when, int64_t delta);
And NSEC_PER_SEC is:
#define NSEC_PER_SEC 1000000000 /* nanoseconds per second */
There are 1,000,000,000 nanoseconds in a second, so I'm going to assume that NSEC_PER_SEC
is defined as 1000000000
.
4
is of type int
4.0
is of type double
Now assuming that an int
contains 32 bits, the range of an int
would be [-2,147,483,648 to 2,147,483,647]
4000000000 > 2147483647
, therefore you'll cause the int
to overflow, which is causing the value to be set to 0.
EDIT: I probably could've worded the above statement better. The overflow could cause the int
(assuming it's 32 bits in size, as stated above) to equal the value -294967296
, and dispatch_time
would be treating any value <= 0
as 0 seconds. That's where the "0" above came from.
A double
variable can hold larger values than an int
, and is able to store an approximation of the value 4000000000
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With