NSInteger,NSUInteger,CGFloat

前导

int:4个字节,一个字节8位,占32位的整数
long:8个字节,占64位的整数
(3)在int与long前加上unsigned 表示无符号
(4)float:占32位的浮点数
(5)double:占64位的浮点数
NSInteger、NSUInteger、CGFloat不是类,而是基本数据类型

NSInteger在32系统中就是int,在64位系统中就是long, 现在咱们的苹果真机都是64位系统
NSUInteger在32系统中就是unsigned int,在64位系统中就是unsigned long
#if __LP64__ || 0 || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif
CGFloat在32位系统中就是float,在64位系统中就是double
#if defined(__LP64__) && __LP64__
# define CGFLOAT_TYPE double
# define CGFLOAT_IS_DOUBLE 1
# define CGFLOAT_MIN DBL_MIN
# define CGFLOAT_MAX DBL_MAX
#else
# define CGFLOAT_TYPE float
# define CGFLOAT_IS_DOUBLE 0
# define CGFLOAT_MIN FLT_MIN
# define CGFLOAT_MAX FLT_MAX
#endif

/* Definition of the `CGFloat' type and `CGFLOAT_DEFINED'. */

typedef CGFLOAT_TYPE CGFloat;
#define CGFLOAT_DEFINED 1
区分单精度和双精度(C 语言浮点数默认是 double 型(双精度浮点数)的)

数后加上f字母,如 2.3f、1.0f 等此类是单精度浮点数(float) 。
数直接写出的数字,如 2.3、1.0 等此类是 double 型的。使用double声明的变量和常1653数版是双精度浮点数权。使用float声明的变量和常数是单精度浮点数。

float是32位,double是64位

float32位中,有1位符号位,8位指数位,23位尾数位
double64位中,1位符号位,11位指数位,52位尾数位
取值范围看指数部分
float是有符号型,其中,8位指数位,28=(-128—127),因此实际的范围是-2128—2^127,约为-3.4E38—3.4E38
同理double范围约是-1.7E308—1.7E308,楼主可以自己按下计算器试试看,印象深些
精度是看尾数部分
float尾数位23位,2^23=8.3E6,7位,所以不同的编译器规定不同,有些是7位,有些8位
double尾数52位,2^52=4.5E15,15位,所以double的有效位数是15位

符号位,指数位,尾数位

在C/C++中float是32位的,double是64位的,两者在内存中的存储方式和能够表示的精度均不同,目前C/C++编译器标准都遵照IEEE制定的浮点数表示法来进行float,double运算。

无论是float还是double,在内存中的存储主要分成三部分,分别是:

(1)符号位(Sign):0代表正数,1代表负数

(2)指数位(Exponent):用于存储科学计数法中的指数部分,并且采用移位存储(127+指数)的二进制方式。

(3)尾数位(Mantissa):用于存储尾数部分

对于两者在内存中的存储结构,如下图所示
数字float 9.125在十进制中用科学计算的方式表示为9.125*10^0 ,但是在计算机中,计算机只认识0和1,所以在计算机中是按照科学计算的二进制的方式表示的:

9的二进制表示为1001
0.125的二进制表示为0.001
所以91.25的表示成1001.001 将其表示成二进制的科学计数方式为 1.001001*2^3

在计算机中,任何一个数都可以表示成1.xxxxxx*2^n 这样的形式,
其中xxxxx就表示尾数部分,n表示指数部分

其中,因为最高位橙色的1这里,由于任何的一个数表示成这种形式时这里都是1,所以在存储时实际上并不保存这一位,这使得float的23bit的尾数可以表示24bit的精度,double中52bit的尾数可以表达53bit的精度。

对于float型数据,可以精确到小数点后几位呢?当然,学过c的同学会说float能够精确到小数点后6位,但这是怎么的来的呢?下面做一点解释:

十进制中的9,在二进制中的表示形式是1001,这里也就告诉我们,表示十进制中的一位数(0到9)在二进制中需要4bit,所以我们现在float中具有24bit的精度,所以float在十进制中具有24(bit)/4(bit/1位)=6(1位),所以在十进制里,float能够精确到小数点后6位。同理,具有53bit精度的double类型能够精确到小数点后13位。

对于float类型,他的指数部分有8bit,可以表示-127~128,但是这里采用了移位存储的方式(对这个概念不太清楚),在存储指数时数据的基数是127,而不是0,。例如上面的9.125,其二进制的指数部分为3,所以在存储时实际上存的是127+3=130。(130的二进制表示为10000010)

最终根据上面图中float的存储结构可以知道,实际上9.125在计算机中:

上面的二进制数转换成十六进制后表示形式为:01000001 00010000 00000000 00000000 --> 41 10 00 00

实际上在X86计算机中,采用的是小端存储方式,即低地址存储低位数据,高地址存储高位数据。

所以数据应该是这样存储的:

对于double类型的存储方式实际上和float是类似的,只是存储的位数不同,在原理上都是一样的。这个可以参考这篇 http://www.linuxidc.com/Linux/2012-07/65987.html 。
原文链接

32位与64位系统基本数据类型的字节数

不同的平台上对不同的数据类型分配的字节数是不同的,一般的,数据类型的字节数是由编辑器决定的(编译期间决定数据类型长度)。

简单来说,平台就是CPU+OS+Compiler,cpu的位是指一次性可处理的数据量是多少,1字节=8位,32位处理器可以一次性处理4个字节的数据量,依次类推。32位操作系统针对的32位的CPU设计。64位操作系统针对的64位的CPU设计。所以平台是三者的组合,它们的字节长相同时,效率最高。
在这里插入图片描述

Java中的long与double的区别

long与double在java中本身都是用64位存储的,本来用的比较简单, 并没有太在意一些细节,大抵就是一个存整数,一个存浮点数。
顺着HBase的一个问题,查了一下stackoverflow,发现了一些比较有意思的事情。
long存的是连续的整数,而对于double,当数很大的时候,它所能表示两个相邻数之间的间隔就会比较大,比如long可以存9223372036854775707和9223372036854775708,而double是无法区分这两个数的。例如:

public class Test1  
{
    public static void main(String[] args) throws Exception 
    {
        long   long1 = Long.MAX_VALUE - 100L;
        double dbl1  = long1;
        long   long2 = long1+1;
        double dbl2  = dbl1+1;
        double dbl3  = dbl2+Math.ulp(dbl2);
 
        System.out.printf("%d %d\n%f %f %f", long1, long2, dbl1, dbl2, dbl3);
    }
 
}

结果为

9223372036854775707 9223372036854775708
9223372036854776000.000000 9223372036854776000.000000 9223372036854778000.000000

想一想,道理在计算机组成原理里面都有,它们的编码决定了这样的结果。

long可以准确存储19位数字,而double只能准备存储16位数字。double由于有exp位,可以存16位以上的数字,但是需要以低位的不精确作为代价。如果需要高于19位数字的精确存储,则必须用BigInteger来保存,当然会牺牲一些性能。

总结记住
NSInteger在32系统中就是int,在64位系统中就是long, 现在咱们的苹果真机都是64位系统
NSUInteger在32系统中就是unsigned int,在64位系统中就是unsigned long
CGFloat在32位系统中就是float,在64位系统中就是double
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值