zoukankan      html  css  js  c++  java
  • 十进制字符串转成二进制(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;
    }


     

  • 相关阅读:
    记一道乘法&加法线段树(模版题)
    2021CCPC网络赛(重赛)题解
    Codeforces Round #747 (Div. 2)题解
    F. Mattress Run 题解
    Codeforces Round #744 (Div. 3) G题题解
    AtCoder Beginner Contest 220部分题(G,H)题解
    Educational Codeforces Round 114 (Rated for Div. 2)题解
    Codeforces Global Round 16题解
    Educational Codeforces Round 113 (Rated for Div. 2)题解
    AtCoder Beginner Contest 182 F
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3297178.html
Copyright © 2011-2022 走看看