Int to Double cast问题

Abh*_*ert 13 c cocoa objective-c grand-central-dispatch

我是一名具有很少C/C++经验(并且没有培训)的Objective-C开发人员,今天我遇到了一些奇怪的硬编码数值.

我确定这是一个简单/愚蠢的问题,但有人可以解释为什么这样做:

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
Run Code Online (Sandbox Code Playgroud)

这也有效(注意秒数已经改变):

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
Run Code Online (Sandbox Code Playgroud)

但这是立即执行的:

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
Run Code Online (Sandbox Code Playgroud)

但是,使用4.0而不是4修复它:

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
Run Code Online (Sandbox Code Playgroud)

为什么1和2正确地转换为相关的双值,但更大的数字(我测试3和4)似乎表示为0

我正在使用Xcode 4.2进行编译,配置为使用LLVM 3.0.

编辑:

dispatch_time_t定义为:

typedef uint64_t dispatch_time_t;
Run Code Online (Sandbox Code Playgroud)

而dispatch_time是:

dispatch_time_t dispatch_time(dispatch_time_t when, int64_t delta);
Run Code Online (Sandbox Code Playgroud)

NSEC_PER_SEC是:

#define NSEC_PER_SEC    1000000000  /* nanoseconds per second */
Run Code Online (Sandbox Code Playgroud)

Aus*_*oke 25

一秒钟内有1,000,000,000纳秒,所以我假设它NSEC_PER_SEC被定义为1000000000.

  • 4 是类型的 int
  • 4.0 是类型的 double

现在假设一个int包含32位,a的范围int将是[-2,147,483,648 to 2,147,483,647]

4000000000 > 2147483647因此,您将导致int溢出,这导致该值设置为0.

编辑:我可能会更好地表达上述声明.溢出可能导致int(假设它的大小为32位,如上所述)等于该值-294967296,并将dispatch_time任何值<= 0视为0秒.这就是上面的"0"来自哪里.

double变量可以比保持较大的值int,并且是能够存储的值的近似值4000000000.


Ant*_*ake 7

前两个工作因为1*10 ^ 9和2*10 ^ 9符合有符号的32位int.但是,4*10 ^ 9将不适合带符号的32位int.

4.0*10 ^ 9有效,因为浮点可以表示该值.

我希望这也会起作用:

dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, ((int64_t)4) * NSEC_PER_SEC);
Run Code Online (Sandbox Code Playgroud)