objective-c C原始数字有什么区别?我知道它们是什么以及如何使用它们(有点),但我不确定每个的功能和用途是什么。任何人都可以清楚哪些情况最适合某些场景而不是其他场景吗?
我可以存储哪些内容?我知道有些可以存储更精确的数字,有些只能存储整数。比方说,我想存储一个纬度(可能从CLLocation
对象中检索),我应该使用哪个来避免丢失任何数据?
我还注意到每个都有unsigned
个变体。这是什么意思,它与未签名的原始数字有何不同?
Apple has some interesting documentation就此而言,但它并不能完全满足我的问题。
答案 0 :(得分:4)
首先,int
,float
,double
,long
和short
等类型是 C 原语,不是Objective-C。您可能知道,Objective-C是C的超集.Abjective-C NSNumber
是所有这些类型的包装类。
所以我会回答你关于这些C原语的问题,以及Objective-C如何解释它们。基本上,每种数字类型可以分为两类:整数类型和浮点类型。
这些只能存储整数(整数),并且具有两个特征: size 和 signedness 。
大小表示类型计算机需要多少物理内存来存储,即多少字节。从技术上讲,为每种类型分配的确切内存是实现依赖,但有一些保证:(1) char
将始终为1字节(2) sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)
。
签名表示该类型是否可以表示负值。因此,有符号整数或int
可以表示一定范围的负数或正数(传统上为-2,147,483,648到2,147,483,647),无符号整数或unsigned int
可以表示相同的数字范围,但是全部为正(0至4,294,967,295)。
这些用于存储小数值(也称为分数),也按大小分类。您唯一真正的保证是sizeof(float) <= sizeof(double) <= sizeof (long double)
。浮点类型使用一种难以理解的特殊内存模型存储,我不会进入,但有一个很好的指南here。
在RyPress的Objective-C上下文中有一篇关于C原语的精彩博文。很多介绍CPS教科书也有很好的资源。
答案 1 :(得分:1)
首先,我想指定au unsigned int和int
之间的区别。假设您的数字非常高,并且您使用unsigned int
编写循环迭代:
for(unsigned int i=0; i< N; i++)
{ ... }
如果N
是使用#define
定义的数字,则可能高于使用int
而不是unsigned int
存储的最大值。如果溢出i
将从零重新开始,你将进入无限循环,这就是为什么我更喜欢使用int
for循环。
如果您使用int
进行迭代,并将其与long
进行比较,则会出现同样的情况。如果N
是long
,您应该使用long
进行迭代,但如果N
是int
,您仍然可以安全地使用long
进行迭代。
可能出现的另一个陷阱是使用带有整数常量的移位运算符,然后将其分配给int
或long
。也许你也记录了sizeof(long)
并且你注意到它返回8
并且你不关心可移植性,所以你认为你不会失去精度:
long i= 1 << 34;
位代替1
不是long
,所以它会溢出,当你把它转换为长时,你已经失去了精度。相反,你应该输入:
long i= 1l << 34;
较新的编译器会警告您这一点。
取自这个问题:Converting Long 64-bit Decimal to Binary。
关于float
和double
有一件事要考虑:他们使用尾数和指数来表示数字。它类似于:
value = 2 ^ exponent *尾数
因此,指数越高,浮点数就越没有精确的表示。也可能会出现一个数字太高,以至于它会有一个如此不准确的表示,令人惊讶的是,如果你打印它会得到一个不同的数字:
float f= 9876543219124567;
NSLog("%.0f",f); // On my machine it prints 9876543585124352
如果我使用double
,则会打印9876543219124568
,如果我使用long double
.0Lf
格式,则会打印正确的值。使用浮点数时要小心,可能会发生意外情况。
例如,也可能发生两个浮点数具有几乎相同的值,您希望它们具有相同的值但存在细微差别,因此相等性比较失败。但是这已经在Stack Overflow上被处理了数百次,所以我将发布这个链接:What is the most effective way for float and double comparison?。