zoukankan      html  css  js  c++  java
  • __c语言__整型、实型的存储(十进制转二进制)

    float 和 double 类型数据在内存中的存储方法

    • 无符号整型采用32位编码,带符号整型数采用1个符号位31位底数编码;
    • 单精度数据采用了1位符号位,8位阶码,23位尾数的编码;
    • 双精度数据采用了1位符号位,10位阶码,52位尾数的编码;

     

    • 无符号整型的范围:0~2的32次方
    • 带符号整型:-2的31次方~2的31次方
    • 单精度规定用 8 位二进制表示阶数,即最大表示为 2 的 128 次方,把这个数算出来是 3.4028236692093846346337460743177e+38
    • 双精度规定用 11 位二进制表示阶数,即最大表示为 2 的 1024 次方,结果是 1.797693134862315907729305190789e+308

     

    • 浮点数(单精度的 float 和双精度的 double)在内存中以二进制的科学计数法表示,表达式为 N = 2^E * F;

    其中E为阶码(采用移位存储),F 为尾数。

     

    • float 和 double 都由符号位阶码尾数三部分组成,float 存储时使用 4 个字节double 存储时使用 8 个字节

    各部分占用位宽如下所示:

                 符号位     阶码      尾数     长度

    float              1           8         23      32

    double          1         11        52      64

    符号位:0代表正数,1代表负数。

    阶码:用移位表示法存储科学计数法中的指数数据

    float阶码占8位,取值范围-128~127,但并没有按照移位表示法+128,而是+127。

    同理double要+1023。阶码也是指数位

    尾数:用二进制的科学计数法表示后,去掉小数点前面恒定的1,只保留小数点后面的二进制数据,存入尾数位置即可。 

     

    • 比如8.25,二进制科学计数法表示为:1.00001*2^3,

    具体转换方法:

    8的二进制1000;

    .25的二进制.01:即0*2^(-1) + 1*2^(-2)。

    写为:1000.01,小数点左移3位,即转换完毕。

    符号位确定:8.25为正数,符号位为0。

    阶码的表示:阶码位3+127=130;二进制10000010,已经是8位。

    尾数的表示:去掉小数点前面的1,为00001,后面补充0至23位:000 0100 0000 0000 0000 0000

    最终8.25在内存里存储的二进制为:0100 0001  0000 0100  0000 0000  0000 0000

     

    • 又比如11.4,二进制科学计数法表示:

    float:1.01101100110011001100110 * 2^3

    double:1.0110  1100 1100  1100 1100  1100 1100  1100 1100  1100 1100  1100 1101 * 2^3

    所以他们的值其实是不同的,因为.4用二进制无法精确表示

    ——这也就是为什么 float 类型数据 和 double 类型数据 都存储11.4,但是对比起来,他们不相等的原因。

    比如 float a = 11.4; double b = 11.4; 要让他们正确对比,((float)b == a),让 double 数据舍弃比 float 多的那些尾数。

     

    • 对于 double 型数据,只要将阶码前面加0扩展到11位,尾数后面补充0至52位即可。

     

    移位表示法

    在数 X 上加一个偏移量,常用于表示浮点数中的阶码(注意阶码的偏移量和移位表示法定义有差别)。

    定义:

    若 X为纯整数,X[移] = 2^(n-1) + X,-2^(n-1) <= X < 2^(n-1);

    若X为纯小数,X[移] = 1 - X,-1<= X < 1

    下面这个代码,我很喜欢,其中有很多思想,对我来说很有用,膜拜下某大神

    #include <stdio.h>  
      
    #define print_float(a) print_bitxx(a, 4)  
    #define print_int(a) print_bitxx(a, 4)  
      
    #define print_double(a) print_bitxx(a, 8)  
      
    int is_little_endian()  
    {  
        short int x = 0x0001;  
        return ((char*)&x)[0];  
    }  
      
    void print_bitxx(const void *a, int bytes)  
    {  
        const unsigned char *pos = (const unsigned char *)a;  
        int i, j;  
        int max_i;
        max_i = bytes - 1;
        if(is_little_endian())
        {  
            for(i=max_i; i>=0; i--)
            {  
                for(j=7; j>=0; j--)
                {  
                    printf("%d", ((pos[i] & (1 << j)) ? 1 : 0));  
                    if (j == 4 || j == 0)  
                        printf(" ");  
                }  
                printf(" ");  
            }  
        }  
        printf("
    ");  
    }  
      
    int main(int argc, char **argv)  
    {
        int a = 8.25;
        float b = 8.25;  
        double c = 8.25;
        
        print_int(&a);  
        print_float(&b);  
        print_double(&c);  
        printf("%d
    ", b == (float) c);  
        printf("%d
    ", (double)b == (double) c);  
        return 0;  
    }  

    然后就是我的学习时间了

    1、编写程序把一个整型二进制数中 1 的个数,最高位1的位置和最低位1的位置显示出来。

    程序接受用户输入的一个整数(分别正数一个,负数一个)

    输出该整数,以及其中 1 的个数最高位 1 的位置最低位 1 的位置

    用GCC编译程序运行,检查程序运行是否正确。

    /*编写程序
        把一个整型二进制数中1的个数,最高位1的位置和最低位1的位置显示出来。
        程序接受用户输入的一个整数(分别正数一个,负数一个),
        输出该整数,
        以及其中1的个数,
        最高位1的位置,
        最低位1的位置。
        
        一个示例的输出如下
               NUMBER: 2049
                 BITS: 2
            HIGHEST 1: 11
             LOWEST 1: 0
        据实验:输入的数字范围是(-2^31) 到 (2^31 - 1) 
                                -2147483648 到 2147483647
        本代码移位运算测试,int 和unsigned int无区别
    */
    #include <stdio.h>
    
    int main(int argc , char *argv[])
    {
        int num = 0;
        int tmp;
        
        int count = 0;
        int highPos = -1;
        int lowPos = -1;
        int flag = 1;
        
        
        printf("   Input : ");
        scanf("%d" , &num);
        
        int i = 0;
    /*******************核心代码*********************/
        while(i != 32 )
        {
            tmp = num&(1<<i); 
            if(tmp)
            {
                highPos = i;
                count++;
                if(flag)
                {
                    lowPos = i;
                    flag = 0;
                }
            }
            i++;
        }
    /************************************************/    
        printf("   NUMBER: %d
    " , num);
        printf("     BITS: %d
    " , count);
        if(count >= 1)
        {//如果有1
            printf("HIGHEST 1: %d
    " , highPos);
            printf(" LOWEST 1: %d
    " , lowPos);
        }
        else
        {//没有1
            printf("HIGHEST 1: 
    ");
            printf(" LOWEST 1: 
    ");
        }
        
        return 0;
    }

    2、编写程序把一个实型二进制数中 1 的个数,最高位 1 的位置 和 最低位 1 的位置 显示出来。

    程序接受用户输入的一个整数(分别正数一个,负数一个)

    输出该整数,以及其中1的个数,最高位1的位置,最低位1的位置。

    用GCC编译程序运行,检查程序运行是否正确。

    /*编写程序
        把一个实型二进制数中1的个数,最高位1的位置和最低位1的位置显示出来。
        程序接受用户输入的一个实型(分别正数一个,负数一个),
        输出该实型,
        以及其中1的个数,
        最高位1的位置,
        最低位1的位置。
        
        root@kjf:/mnt/hgfs/workPlace/01_computer/20170914# ./a.out 
               Input : 8.25
               NUMBER: 0100 0001  0000 0100  0000 0000  0000 0000  
                 BITS: 3
            HIGHEST 1: 30
             LOWEST 1: 18
    */
    #include <stdio.h>
    
    #define print_float(a) print_bitxx(a, 4)        //访问对象地址,访问对象大小float为4字节
    
    int count;
    int posHex;
    
    int highPos;
    int lowPos;
    
    int highFlag;
    int lowFlag;
    
    //判断小端模式
    int is_little_endian()        
    {  
        short int x = 0x0001;  
        return ((char*)&x)[0];  
    }
    
    //访问对象地址,访问对象大小float为4字节。。。打印存储的二进制数
    void print_bitxx(const void *a, int bytes)
    {
        int bit;
        const unsigned char *pos = (const unsigned char *)a;  
        int i, j;  
        int max_i;
        max_i = bytes - 1;
        if(is_little_endian())
        {//此程序只适用小端模式,因为是根据指针访问存储数据
            for(i=max_i; i>=0; i--)
            {  
                for(j=7; j>=0; j--)
                {  
                    bit= ((pos[i] & (1 << j)) ? 1 : 0);
                    printf("%d", bit);
                    /************************************/
                    if(bit == 1)
                    {//如果是1
                        if(highFlag == 0)
                        {
                            highFlag = 1;
                            highPos = posHex;
                        }
                        lowPos = posHex;
                        count++;
                    }
                    posHex--;
                    /************************************/
                    if (j == 4 || j == 0)  
                        printf(" ");  
                }  
                printf(" ");  
            }  
        }  
        printf("
    ");  
    }
    
    int main(int argc , char *argv[])
    {
        float num = 0;
        
        /*************参数初始化************/
        count = 0;
        posHex = 31;
        
        highPos = -1;
        lowPos = -1;
        
        highFlag = 0;
        lowFlag = 0;
        
        /***********************************/
        printf("   Input : ");
        scanf("%f" , &num);
        
        /***********************************/
        printf("   NUMBER: ");
        print_float(&num);
        
        printf("     BITS: %d
    " , count);
        if(count >= 1)
        {//如果有1
            printf("HIGHEST 1: %d
    " , highPos);
            printf(" LOWEST 1: %d
    " , lowPos);
        }
        else
        {//没有1
            printf("HIGHEST 1: 
    ");
            printf(" LOWEST 1: 
    ");
        }
        
        return 0;
    }

     http://canlynet.iteye.com/blog/1796889

    --------小尾巴 ________一个人欣赏-最后一朵颜色的消逝-忠诚于我的是·一颗叫做野的心.决不受人奴役.怒火中生的那一刻·终将结束...
  • 相关阅读:
    SpringBoot入门系列
    日志收集系统-多线程消息队列
    阿里云ecs 服务器配置
    MySQL 表分区详解MyiSam引擎和InnoDb 区别(实测)
    Redis 3.2 Linux 环境集群搭建与java操作
    Java
    多线程编程-工具篇-BlockingQueue
    java常见面试题及答案 11-20(JVM篇)
    28.function_score自定义相关度分数算法
    27.四种常见的相关度分数优化方法
  • 原文地址:https://www.cnblogs.com/tianxiaxuange/p/7531237.html
Copyright © 2011-2022 走看看