Task: Decimal floating point number to binary





Java: import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;

public class DecimalToBinary {

    public static void main(String[] args) {
        for ( String s : new String[] {"23.34375", ".1", "3.1415926535897932"} ) {
            String binary = decimalToBinary(new BigDecimal(s));
            System.out.printf("%s => %s%n", s, binary);
            System.out.printf("%s => %s%n", binary, binaryToDecimal(binary));
        }
    }

    private static BigDecimal binaryToDecimal(String binary) {        
        return binaryToDecimal(binary, 50);
    }

    private static BigDecimal binaryToDecimal(String binary, int digits) {
        int decimalPosition = binary.indexOf(".");
        String integer = decimalPosition >= 0 ? binary.substring(0, decimalPosition) : binary;
        String fractional = decimalPosition >= 0 ? binary.substring(decimalPosition+1) : "";

        
        BigDecimal result = BigDecimal.ZERO;
        BigDecimal powTwo = BigDecimal.ONE;
        BigDecimal two = BigDecimal.valueOf(2);
        for ( char c : new StringBuilder(integer).reverse().toString().toCharArray() ) {
            result = result.add(powTwo.multiply(BigDecimal.valueOf(c - '0')));
            powTwo = powTwo.multiply(two);
        }
        
        
        MathContext mc = new MathContext(digits);
        powTwo = BigDecimal.ONE;
        for ( char c : fractional.toCharArray() ) {
            powTwo = powTwo.divide(two);
            result = result.add(powTwo.multiply(BigDecimal.valueOf(c - '0')), mc);
        }
        
        return result;
    }
    
    private static String decimalToBinary(BigDecimal decimal) {
        return decimalToBinary(decimal, 50);
    }
    
    private static String decimalToBinary(BigDecimal decimal, int digits) {
        BigDecimal integer = decimal.setScale(0, RoundingMode.FLOOR);
        BigDecimal fractional = decimal.subtract(integer);
        
        StringBuilder sb = new StringBuilder();

        
        BigDecimal two = BigDecimal.valueOf(2);
        BigDecimal zero = BigDecimal.ZERO;
        while ( integer.compareTo(zero) > 0 ) {
            BigDecimal[] result = integer.divideAndRemainder(two);
            sb.append(result[1]);
            integer = result[0];
        }
        sb.reverse();
        
        
        int count = 0;
        if ( fractional.compareTo(zero) != 0 ) {
            sb.append(".");
        }
        while ( fractional.compareTo(zero) != 0 ) {
            count++;
            fractional = fractional.multiply(two);
            sb.append(fractional.setScale(0, RoundingMode.FLOOR));
            if ( fractional.compareTo(BigDecimal.ONE) >= 0 ) {
                fractional = fractional.subtract(BigDecimal.ONE);
            }
            if ( count >= digits ) {
                break;
            }
        }
        
        return sb.toString();
    }

}



Python: hex2bin = dict('{:x} {:04b}'.format(x,x).split() for x in range(16))
bin2hex = dict('{:b} {:x}'.format(x,x).split() for x in range(16))

def float_dec2bin(d):
    neg = False
    if d < 0:
        d = -d
        neg = True
    hx = float(d).hex()
    p = hx.index('p')
    bn = ''.join(hex2bin.get(char, char) for char in hx[2:p])
    return (('-' if neg else '') + bn.strip('0') + hx[p:p+2]
            + bin(int(hx[p+2:]))[2:])

def float_bin2dec(bn):
    neg = False
    if bn[0] == '-':
        bn = bn[1:]
        neg = True
    dp = bn.index('.')
    extra0 = '0' * (4 - (dp % 4))
    bn2 = extra0 + bn
    dp = bn2.index('.')
    p = bn2.index('p')
    hx = ''.join(bin2hex.get(bn2[i:min(i+4, p)].lstrip('0'), bn2[i])
                 for i in range(0, dp+1, 4))
    bn3 = bn2[dp+1:p]
    extra0 = '0' * (4 - (len(bn3) % 4))
    bn4 = bn3 + extra0
    hx += ''.join(bin2hex.get(bn4[i:i+4].lstrip('0'))
                  for i in range(0, len(bn4), 4))
    hx = (('-' if neg else '') + '0x' + hx + bn2[p:p+2]
          + str(int('0b' + bn2[p+2:], 2)))
    return float.fromhex(hx)