iphone arm32 & base64 基础数据类型疑问

事情如下:

/*
    long a1 =145463470;
    long a2 = 33;
    long a3 = a1*a2;
 */

 ---------------------------

一般处理,都没太多想法,可Iphone出了新版本架构 64位的 iphone  5s,6,6s

/*
 32Bit   -  505327214
 64Bit   -  4800294510
 */

 ------------------------------------------------------

于是想着可能是 double 在不同的cpu指令架构下,有不同的字节长度.于是继续实验.

 1 -(void) typeSizeBit
 2 {
 3     unsigned char uint8 = 0;
 4     signed char int8 = 0;
 5     unsigned short uint16 = 0;
 6     signed short int16 = 0;
 7     unsigned int uint32 = 0;
 8     signed int int32 = 0;
 9     float fp32 = 0;
10     double fp64 = 0;
11     unsigned long ulong = 0;
12     long  llong = 0;
13     int   iint  = 0;
14    
15     printf("unsigned char is %d bit

", sizeof(uint8)*8);
16     printf("signed char is %d bit

", sizeof(int8)*8);
17     printf("unsigned short is %d bit

", sizeof(uint16)*8);
18     printf("signed short is %d bit

", sizeof(int16)*8);
19     printf("unsigned int is %d bit

", sizeof(uint32)*8);
20     printf("signed int is %d bit

", sizeof(int32)*8);
21     printf("float fp32 is %d bit

", sizeof(fp32)*8);
22     printf("double fp64 is %d bit

", sizeof(fp64)*8);
23     printf("unsigned long is %d bit

", sizeof(ulong)*8);
24     printf("long is %d bit

", sizeof(llong)*8);
25     printf("int is %d bit

", sizeof(iint)*8);
26 
27 }

日志输出如下:

/*
     iphone5  arm7 32位cpu指令集架构
     ---------------------------
     -- unsigned char is   8 bit
     -- signed char is     8 bit
     -- unsigned short is  16 bit
     -- signed short is    16 bit
     -- unsigned int is    32 bit
     -- signed int is      32 bit
     -- float fp32 is      32 bit
     -- double fp64 is     64 bit
     -- unsigned long is   32 bit
     ---------------------------
     
     iphone6  arm64  64指令集架构
     ---------------------------
     -- unsigned char is   8 bit
     -- signed char is     8 bit
     -- unsigned short is  16 bit
     -- signed short is    16 bit
     -- unsigned int is    32 bit
     -- signed int is      32 bit
     -- float fp32 is      32 bit
     -- double fp64 is     64 bit
     -- unsigned long is   64 bit
     ---------------------------
     */

 ---------------------------

可见long类型在不同的cpu指令集架构下,位数不一样。

但问题是,为什么 double类型在 32位系统下面,数值反而减小了呢?

这是个问题,暂时还没搞清楚原因- 

截止时间   2015.10.28   13:19

 --------------------------- --------------------------- --------------------------- --------------------------- ---------------------------

10.29   11:06

昨天的问题想了挺久,翻了不少文章,其中翻到一遍讲 64位计算程序注意点说明 的文章,文中提到了【在32位系统中long和int的长度是一样的,不过在64位系统中就有可能出问题,因为64位系统中long比int长,将long值赋予int将导致数据丢失。】,顿时让我觉得肯定是 long类型在32位与64位的字节长度问题,引起的溢出,才导致结果不一样。

于是我开始做实验,过程如下:

1 -(void)long64BitTest
2 {
3     uint64_t a1 =145463470;
4     uint64_t a2 = 33;
5     uint64_t a3 = a1*a2;
6     
7     return;
8 }

---------iphone5 arm7  32位  输出结果-------------

---------------------------
--  uint64_t a3 = 4800294510

---------------------------

---------iphone6 base64  64位  输出结果-------------

---------------------------
--  uint64_t a3 = 4800294510

---------------------------

果然,终于结果是一致的了,其中 uint64_t   定义为: typedef unsigned long long uint64_t; 共 8个字结长度,共 64位,最大值: 1.84467440737096E19

适用于大数据的计算。

而 我们再看一组对比:

1 -(void)long32BitTest
2 {
3     long a1 =145463470;
4     long a2 = 33;
5     uint64_t a3 = a1*a2;
6     
7     return;
8 }

---------iphone5 arm7  32位  输出结果-------------

---------------------------
--  uint64_t a3 = 505327214

---------------------------

---------iphone6 base64  64位  输出结果-------------

---------------------------
--  uint64_t a3 = 4800294510

---------------------------

其结果也出人意料,即然知道a1*a2 出来的结果是大数据,只能用 64位类型定义,但为什么出来的结果却不是正确的 4800294510。

原因是这样的, a1与a2是Long型,在 32位系统下面,long型最大值为  4294967296.  而a1*a2 单独运算后,才会赋值给 a3.    而a1*a2在 32位的Long下面,已经溢出为505327214,

其结果可想而知了。

综合上述,为了移植的正确性,我们在进行大数据运算的时候,可以定为 long long类型,这样就能保证定义的变量为  64位长度值。

然后,我实验了一下android系统下面,long值为 64位,没有无符号类型,最大值为 1.84467440737096E19 ,基本能满足运算的要求。

++++++++++++++++++++++++++++++++++

IOS版本 ---> 自定义哈希函数

-------------------------------------------------------------

 1 -(int) hashCode:(NSString*) tmpStr
 2 {
 3     double
 4     int hash = 0;
 5     
 6     int i=0;
 7     
 8     
 9     const char *chatlist = [tmpStr UTF8String];
10     int ad=33;
11     for (i=0; i<tmpStr.length; ++i) {
12         
13         int  adhash = ad*hash;
14         hash = adhash + chatlist[i];
15         //printf("%c - %d -%d - %d
",chatlist[i],chatlist[i],hash,adhash);
16     }
17     
18     
19     if (hash<0) {
20         hash = -1 * hash;
21     }
22 
23     return hash;
24 }
25 
26 - (void)viewDidLoad {
27     [super viewDidLoad];
28     // Do any additional setup after loading the view, typically from a nib.
29     
30     //[self hashCode];
31     
32     NSArray *arStringList = @[@"wuxian",@"无线天下",@"temobi长778844Ok",@"234xxxxxxxxxxxxxxxxxxxx324234234234234234"];
33     for (NSString *str in arStringList) {
34         NSLog(@"%d,", [self hashCode:str]);
35     }
36   
37     return;
38 }

++++++++++++++++++++++++++++++++++

Android版本 ----->

-------------------------------------------------------------

 1 /**
 2      * @param 哈希值
 3      * @return
 4      */
 5     public static  int bernstein(String key) {
 6         int hash = 0;
 7         int i;
 8         for (i = 0; i < key.length(); ++i)
 9             hash = 33 * hash + key.charAt(i);
10         return hash;
11     }
12     
13     
14     @Override
15     protected void onCreate(Bundle savedInstanceState) {
16         
17          //typeSizeBit();
18         String[] array=new String[4];
19         array[0]="wuxian";
20         array[1]="无线天下";
21         array[2]="temobi长778844Ok四";
22         array[3]="234xxxxxxxxxxxxxxxxxxxx324234234234234234";
23 
24 
25    for(int i=0;i<array.length;i++){
26             int tempCode = bernstein(array[i]);
27             Log.e("info", String.format("%d",tempCode) );
28         }
29 
30 }

通过实验,修改后的,统一 自定义哈希code 函数如下:

+++++++++++++IOS版本+++++++++++++++++++++++

 1 -(int) hashCode:(NSString*) tmpStr
 2 {
 3     
 4     int i    = 0;
 5     int ad   = 33;
 6     int hash = 0;
 7     
 8     for (i=0; i<tmpStr.length; ++i) {
 9         int  adhash = ad*hash;
10         unichar cAT = [tmpStr characterAtIndex:i];
11         hash = adhash + cAT;
12     }
13     
14     if (hash<0) {
15         hash *= -1;
16     }
17     
18     return hash;
19 }

-------> 测试代码

1 NSArray *arStringList = @[@"wuxian",@"无线天下",@"temobi长778844Ok四",@"234xxxxxxxxxxxxxxxxxxxx324234234234234234"];
2     for (NSString *str in arStringList) {
3         NSLog(@"%d,", [self hashCode:str]);
4     }

+++++++++++++Android版本+++++++++++++++++++++

 1 public static  int bernstein(String key) {
 2         int hash = 0;
 3         int i;
 4         for (i = 0; i < key.length(); ++i)
 5         {
 6             hash = 33 * hash + key.charAt(i);
 7         }
 8         
 9         if(hash<0) hash *= -1;
10         
11         return hash;
12     }

-------> 测试代码

 1 public void onCreate(Bundle savedInstanceState)
 2     {
 3         String[] array=new String[4];
 4         array[0]="wuxian";
 5         array[1]="无线天下";
 6         array[2]="temobi长778844Ok四";
 7         array[3]="234xxxxxxxxxxxxxxxxxxxx324234234234234234";
 8         
 9         for(int i=0;i<array.length;i++)
10            {
11             int tempCode = bernstein1(array[i]);
12             Log.e("GallaryTest", String.format("%d",tempCode) );
13         }
14 }

++++++++++++++++++++++++++++++++++

输出结果值如下:

505327324,
973344947,
1438764634,
1926919377

++++++++++++++++++++++++++++++++++

转载介绍64位说明文章 [http://blog.csdn.net/fhbystudy/article/details/12752967]

随着iPhone5S的推出,大家开始关心5S上所使用的64位CPU A7。

除了关心A7的性能以外,大家还会关心一个问题,那就是使用A7的64位系统对应用有没有什么要求。特别是应用开发者,大家都比较关心我们的应用如 何迁移到 64位的系统上来,以充分发挥A7的能力。其实这些问题都可以在苹果的官方文档《64-Bit transition Guide for Cocoa Touch》中找到答案。

为了方便大家,我将《64-Bit transition Guide for Cocoa Touch》中的一些重点整理了一下,希望可以为大家节约一些详细阅读文档的时间,如果我理解有不对的地方请大家指正。

首先,A7使用的是ARM V8架构,除了使用64位的地址总线和64位的寄存器以外,还增加了寄存器的数量,目前A7中的整数和浮点数寄存器是A6的两倍。

这里需要强调的是,寄存器的增加大大提高了程序的运行速度。将CPU由32位提高到64位,最主要的改变增大了寻址能力,可以突破32位系统只能访 问3G内存的限制(32位系统在理论上可以访问4G内存,因为2的32次方约等于4 290 000 000,很多32位系统只能访问3G左右的内存是因为有一大部分地址被分配给I/O系统了,所以总体可用内存就不足4G了),但是,32位到64位的改变 并不一定意味着程序运行速度的提高,甚至有些情况下会因为64位系统中的数据占用内存变大而导致程序运行速度变慢。而寄存器数量的增加,则直接提高了程 序运行速度,当然,前提是你的应用需要重新为64位系统编译一遍,让程序可以充分使用所有的寄存器。

使用Xcode 5可以很方便地将以前的应用编译成64位程序,基本过程如下:

  • 1. 使用Xcode 5 打开原有项目。
  • 2. 将支持的设备改成“iOS 7”。
  • 3. 在“Build Setting”中将“Architectures”改成“Standard Architectures (including 64-bit)”。
  • 4. 运行测试程序,解决编译过程出现的问题。

其中第4步是关键,具体会遇到什么问题和原来程序的设计有关,包括使用数据类型的方式是否标准等,后面会继续讨论细节,其实《64-Bit transition Guide for Cocoa Touch》一书主要就是讲这些细节。

在讨论细节之前有一些较为宏观的内容大家可以了解一下。

Xcode 5编译的iOS 7程序包含了32位和64位两套二进制代码,在32位的iOS系统上会调用32位的二进制代码,在64位系统上会调用64位的二进制代码,以此来解决向后兼容的问题。

同时,考虑到很多32位的程序可能在没有重新编译的情况下部署到64位系统上,64位的iOS系统中带有两套FrameWork,一套是32位的,一套是64位的。

当64位的iOS系统运行原来的32位程序时,系统会调用32位的FrameWork作为底层支撑,当系统运行64位程序时,系统会调用64位的FrameWork作为底层支撑。

也就是说,当一个iPhone 5S上同时运行32位程序和64位程序时,系统同时将32位和64位两套FrameWork载入了内存中,所以消耗的内存也比较多。

如果一台64位的iOS设备上运行的所有程序都是为64位系统编译过的,iOS系统将只载入64位的FrameWork,这将节省好多内存。所以,如果大家都可以快速将程序传换成64位的,iOS将跑得更快。真的是“大家好才是真的好”。

后面我们来看看一些为64位系统调整程序的技术细节。

32位的iOS系统和64位的iOS系统主要的差别有两个,一个是数据类型的差别,一个是过程调用方法的差别。

在数据类型上,主要的变化是指针类型(Pointer)和长整数类型(long)的长度变化和内存对齐方式的变化,同时也导致了更高级别数据类型的变化,如NSInteger的长度也有变化。

在过程调用方法上,因为ARM V8 和ARM V7具有不同数量的寄存器,具有不同的过程调用约定,所以32位系统和64位系统在汇编层级是不同的。

根据以上两方面的变化,书中总结了以下要点,开发人员根据以下要点来检查原来的32位代码就差不多可以将应用移植到64位系统上了:

1. 不要将长整型数据(long)赋予整型(int)

这种代码在32位系统上没有问题,因为在32位系统中long和int的长度是一样的,不过在64位系统中就有可能出问题,因为64位系统中long比int长,将long值赋予int将导致数据丢失。

2. 不要将指针类型(Pointer)赋予整型(int)

为 了方便地址计算,有时程序员会将指针类型赋予整型,这种代码在32位系统上没有问题,因为在32位系统中Pointer和int的长度是一样的,不过在 64位系统中就会有问题,因为64位系统中Pointer比int长,将Pointer值赋予int将导致地址数据丢失,最终导致严重问题。

3. 留意那些和数位相关的数值计算

比如掩码技术,如果使用一个long类型的掩码,转到64位系统后高位都是0,计算出来的结果可能不符合预期。还有无符号整数和有符号整数的混用等。

4. 留意对齐方式带来的变化

如果在32位系统上定义一个结构包含两个long类型,第二个long数值的偏移地址是4,可以通过结构地址+4的方式获取,但是在64位系统上就不行了,因为在64位系统中第二个long数值的偏移地址是8。

5. 充分考虑在32位应用和64位应用之间的数据交换

因 为用户会通过网络交换数据,同时用户保存的数据也可能通过备份等方式在32位系统和64位系统之间切换,所以应用在保存和发送流数据的时候一定要考虑充 分。比如数据在32位系统中保存,在64位系统中能否正常打开,或者反过来,在64位系统中保存,在32位系统中打开是否正常。

6. 重写所有汇编代码

这点无需说明,如果你在代码中嵌入了汇编代码,你需要参考64位系统的指令集重写汇编代码。

7. 不要将可变参数的过程强制转换为定参过程,也不要将定参过程强制转换为可变参数的过程

这时因为32位系统和64位系统对于这两种过程调用方式的处理方法不同。

按以上几个重点去检查程序就差不多了,当然,具体的细节还有很多,需要在实际工作中结合代码和调试结果进行分析。

总之,建议具体负责应用迁移的开发者需要完整阅读《64-Bit transition Guide for Cocoa Touch》。

原文地址:https://www.cnblogs.com/chensheng12330/p/4919053.html