• 算法习题---3.12浮点数(UVa11809)


    一:题目

    尴尬的非会员水印

    二:题目摘要

    1.int和float比较

    int共32位,可以表示的最大的数为2^32次方
    float虽然也是32位,但是是以指数形式保存,指数占8位(含符号),最大127,则表示最大数为2^127,可以表示到10^38次方数

    2.float在内存中存在形式

    其中尾数部分,默认前面省略了一个1

    3.输入数据的范围

    9.205357638345294e18
    5.699141892149156e76  -->不能单纯用float表示
    0e0
    double类型指数占11位,最高可以表示到10^308次方,可以满足输入条件

    三:解题思路

    (一)整数部分除2,小数部分乘2

    例如:19.625

    整数

    19/2 = 9...1
    9/2=4...1
    4/2=2...0
    2/2=1...0
    1/2=0...1
    19 = 10011

    小数

    0.625*2 = 1.25   -->  1
    0.25*2 = 0.5  -->  0
    0.5*2 = 1.0 -->  1
    0.625 = 0.101

    (二)位数确定(2^10=1024)>10^3>(2^9=512)

    Xe18位数范围为18/3*9到(18/3+1)*10之间--->其中18/3+1中+1是为了防止X带来的误差(例如X=8就是2^3,所以我们不妨直接将其扩大10位,即1*10)

    (三)函数pow的参数是double类型,返回也是double类型

    (四)为了在处理小数时方便计算,将double类型转float(两种保留位数不同,float位数较少)

    四:数据展示

    9.205357638345294e18
    5.699141892149156e76
    0e0
    8 6
    5 8

    五:代码分析

    (一)获取指数值

            bit = 0;
            while (temp>1)
            {
                temp /= 10;
                bit++;
            }
            bit--;   //bit是整数位数(1000.1就是bit=3)
            for (bin_bit = bit / 3 * 9; bin_bit <= (bit / 3 + 1) * 10; bin_bit++)
            {
                if ((num / pow(2.0, bin_bit)) < 1)
                    break;
            }
    其中num是我们获取的需要处理的最大浮点数
    bin_bit是根据三(二)中确定的值,循环次数从bit/3*9到(bit/3+1)*9,
    当num/pow(2.0,bin_bit)小于1时,就是处理了所有的的指数值

    (二)根据指数值,获取尾数值

            //指数是bin_bit位
            //尾数是num / pow(2.0, bin_bit)
            mant_val = num / pow(2.0, bin_bit);    //double转float只是为了保留15位小数,方便后面比较运算
            expo_val = bin_bit;

    (三)根据三(一)获取指数值位数

            while (expo_val)
            {
                expo++;  //初始为0
                expo_val /= 2;
            }

    (四)根据小数运算获取小数位数

            while (mant_val>1e-15)  //因为float有效位数15位
            {
                if (mant_val * 2 >= 1.0)
                    mant_val = mant_val*2 - 1;
                else
                    mant_val = mant_val * 2;
    
                mant++;
            }

        
    mant--; //因为有一个1被默认省略,所以减去

    六:代码实现

    //浮点数求尾数和指数位数
    //整数部分除2,小数部分乘2
    void test37()
    {
        double num, temp;    //考虑位数,取double类型
        int bit,bin_bit;
        float mant_val;    //尾数值
        int expo_val;    //指数值
        int mant, expo;  //尾数位数和指数位数
        freopen("data.in", "r", stdin);
        freopen("data.out", "w", stdout);
    
        while (1)
        {
            scanf("%lf", &num);  //注意:double类型读取时,使用lf
            expo = mant = 0;
    
            temp = num;    
            if (temp == 0)
                break;
    
            bit = 0;
            while (temp>1)
            {
                temp /= 10;
                bit++;
            }
            bit--; 
    
            for (bin_bit = bit / 3 * 9; bin_bit <= (bit / 3 + 1) * 10; bin_bit++)
            {
                if ((num / pow(2.0, bin_bit)) < 1)
                    break;
            }
            //指数是bin_bit位
            //尾数是num / pow(2.0, bin_bit)
            mant_val = num / pow(2.0, bin_bit);    //double转float只是为了保留15位小数,方便后面比较运算
            expo_val = bin_bit;
    
            while (expo_val)
            {
                expo++;
                expo_val /= 2;
            }
    
            while (mant_val>1e-15)
            {
                if (mant_val * 2 >= 1.0)
                    mant_val = mant_val*2 - 1;
                else
                    mant_val = mant_val * 2;
    
                mant++;
            }
    
            mant--;    //因为有一个1被默认省略,所以减去
            
            printf("%d %d
    ", mant, expo);
        }
    
        freopen("CON", "r", stdin);
        freopen("CON", "w", stdout);
    }
  • 相关阅读:
    Flink学习四:Flink运行架构
    Flink学习三:Flink安装
    Flink学习二:Flink基本架构
    进程的作业
    并发编程
    粘包解决模板
    网络下载作业
    网络通信远程操控
    网络编程套接字
    网络编程基础之网络协议篇
  • 原文地址:https://www.cnblogs.com/ssyfj/p/10818380.html
Copyright © 2020-2023  润新知