zoukankan      html  css  js  c++  java
  • 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》。

  • 相关阅读:
    针对大数据量 高并发量网站的解决方案
    session cookie 在用户登录中的使用
    彻底弄懂HTTP缓存机制及原理
    cookie 和session 的区别详解
    常见的浏览器兼容性问题
    内容分发网络(CDN)
    表现与数据分离、Web语义化
    关于bootstrap样式重写,无法覆盖的问题
    判断一个字符串中出现次数最多的字符
    [译]SQL Passion Week 10: 计划缓存
  • 原文地址:https://www.cnblogs.com/chensheng12330/p/4919053.html
Copyright © 2011-2022 走看看