• 十进制字符串转成二进制(decimal to binary)


    题目:给一个十进制的字符串例如1.25, 将其转化为二进制字符串,这个例子的结果是1.01 = 1*2^0 + 0*2^(-1) + 1*2^(-2) = 1.25。 如果不能完整的用二进制表示,输出ERROR

    思路:首先整数部分和小数部分的做法不同,需要区分开。

    先说整数部分,假设整数部分是n:

    这个很简单,不断的对2取余然后数除2就行。例如5转成二进制:

    n=13

    n%2 = 1 ; n=n/2=6

    n%2 = 0 ; n=n/2=3

    n%2 = 1 ; n=n/2=1

    n%2 = 1 ; n=n/2=0

    结果就是1101,要注意先算的是低位,后算的是高位。


    然后是小数部分,小数部分就不是除了,而是乘法了。

    算法:每次乘以2,取整数部分就是下一位二进制值,然后减去整数部分只,剩下的小数部分继续 。

    n=0.375

    十进制值                 整数部分值             二进制序列            减去整数部分剩余的小数

    n*2=0.75                   0                                 0                                     n=0.75

    n*2=1.5                     1                                 1                                     n= 0.5

    n*2=1                        1                                 1                                      n=0

    所以0.375的二进制序列表示为 0.011


    但是有一个问题,怎么样判断十进制是否可以用二进制完全表示呢?

    结论:如果一个十进制小数能够用二进制表示,那么十进制小数的小数位数和二进制表示的小数位数是相等的。

    理解也很简单:

    2^(-1) = 0.1

    2^(-2) = 0.25

    2^(-3) = 0.125

    2^(-4) = 0.0625

     .....

    每多除一个2,小数位数就增加一个。一般的有2^(-n)的十进制正好是n位,而且最后一位肯定是5.

    那每个二进制表示的数n=0.a1a2a3...an (ai=0或1)

    它的十进制值是:a1*2^(-1)+a2*2^(-2)+...an*2^(-n)

    我们只需要看最后的an*2^(-n),它需要用n位小数表示,而前面的都是少于n位的,那么相加的话也就是n位的小数了。所以上面的结论就成立了。


    所以现在给定一个小数n,假设它小数是k位的,那么我们最多算k次就应该可以算完,得到二进制表示,如果乘了k次2之后,依然还有小数部分,说明这个数是不能用二进制表示的。

    下面附上代码:后期会开放github,有任何问题请留言或者在微博上@evagle,thanks!

    /**
     * @file Decimal2Binary5-2.cpp
     * @Brief 
     * @author  Brian 
     * @version 1.0
     * @date 2013-09-02
     */
    
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <math.h>
    using namespace std;
    
     
    /**
     * Test case:
     * 1. 0  0 
     * 2. 2  10
     * 3. 13 1101
     * 4. 0.25 0.01
     * 5. 0.1  ERROR
     * 6. 2.25 10.01
     * 7. 2.1  ERROR
     *
     */
    char* decimal2binary(char* decimal){
        int integer = 0;
        double fraction = 0;
        int fraction_count = 0;
        int i=0;
        for(;i<strlen(decimal);i++){
            if(decimal[i] == '.'){
                break;
            }else{
                integer = integer*10 + (decimal[i]-'0');
            }
        }
        double rate = 10;
        for(i=i+1;i<strlen(decimal);i++){
            fraction = fraction+(decimal[i]-'0')/rate;
            rate*=10;
            fraction_count++;
        }
        
        int bin_int[100];
        int int_count=0;
        while(integer){
            bin_int[int_count++]=integer%2;
            integer/=2;
        }
        // decimal<1;
        if(int_count==0){
            int_count++;
            bin_int[0]=0;
        }
    
        int bin_fraction[100];
        int bin_frac_count =0;
        while(fraction_count--){
            fraction*=2;
            if(fraction-1 >= 0 ){
                bin_fraction[bin_frac_count++] = 1;
                fraction-=1;
            }else{
                bin_fraction[bin_frac_count++] = 0;
            }
        }
        if(fraction>1e-9)
            return "ERROR";
        else{
            char* binary= new char[200];
            int ptr=0;
            for(int i=int_count-1;i>=0;i--){
                binary[ptr++]=bin_int[i]+'0';
            }
            if(bin_frac_count>0){
                binary[ptr++]='.';
                for(int i=0;i<bin_frac_count;i++){
                    binary[ptr++]=bin_fraction[i]+'0';
                }
            }
            binary[ptr]='';
            return binary;
        }
    }
    
    int main(){
        char* str = "2.11";
        cout<<decimal2binary(str)<<endl;
        return 0;
    }


     

  • 相关阅读:
    iOS 语录
    接口的理解
    android中src和background区别
    onItemClick 参数解释
    工作空间项目不存在,eclipse中项目删不掉
    [转载] IIS来搭建一个只能实现基本功能的FTP服务器
    [转]C# FTP操作类
    [转] VS2017 打包安装程序
    笔记本睿频的关闭与开启 [转载]
    C# 线程:定时器的使用
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3297178.html
Copyright © 2020-2023  润新知