Как преобразовать десятичную дробь в двоичную в Java?

Мне нужно преобразовать 0,5 по основанию 10 в основание 2 (0,1). я пытался использовать

Double.doubleToRawLongBits(0.5)

и он возвращает 4602678819172646912, который, я думаю, находится в шестнадцатеричном формате, но для меня это не имеет смысла.


person iddober    schedule 16.04.2009    source источник


Ответы (5)


Умножьте число на 2^n, преобразуйте в BigInteger, преобразуйте в двоичную строку, добавьте десятичную точку в позицию n (справа налево).

Пример (быстрый и ++ грязный):

private static String convert(double number) {
    int n = 10;  // constant?
    BigDecimal bd = new BigDecimal(number);
    BigDecimal mult = new BigDecimal(2).pow(n);
    bd = bd.multiply(mult);
    BigInteger bi = bd.toBigInteger();
    StringBuilder str = new StringBuilder(bi.toString(2));
    while (str.length() < n+1) {  // +1 for leading zero
        str.insert(0, "0");
    }
    str.insert(str.length()-n, ".");
    return str.toString();
}
person user85421    schedule 16.04.2009
comment
Почему мы взяли здесь n=10? - person Constantine; 20.12.2016
comment
быстро и ГРЯЗНО, то есть количество цифр после запятой - выбрано произвольно... (может быть аргументом метода) - person user85421; 07.01.2017
comment
не могли бы вы сделать это, используя рекурсию. @КарлосХойбергер - person Ashish Kumar Pal; 05.10.2017
comment
@AshishKumarPal единственный цикл для добавления 0; почему это должно быть сделано с рекурсией? - person user85421; 05.10.2017

№ 4602678819172646912 в dec, шестнадцатеричный 0x3fe00000000000000. Чтобы демонтировать это:

   3   |   F   |   E   |  0 ...
0 0 1 1 1 1 1 1 1 1 1 0 0 ...
s|  exponent         |  mantissa

s — бит знака, показатель степени — показатель степени, сдвинутый на 2^9 (следовательно, этот показатель степени означает —1), мантисса — часть xxx числа 1.xxx (подразумевается 1.). Следовательно, это число равно 1.000...*2^-1, что равно 0,5.

Обратите внимание, что это описывает только «нормальные» числа, поэтому никаких нулей, денормалей, NaN или бесконечностей

person jpalecek    schedule 16.04.2009
comment
Не могли бы вы дать мне код, который принимает 0,5 по основанию 10 и дает мне 0,1 (по основанию 2) - person iddober; 16.04.2009

Это десятичное число для 0x3FE0_0000_0000_0000. Мантисса — это список нулей после 3FE (который кодирует знак и показатель степени). Это то, что вы ищете, учитывая, что 0,1 перед нулями неявно.

person mouviciel    schedule 16.04.2009
comment
Хорошо, как преобразовать 0x3FE0_0000_0000_0000 в строку 0.1? - person iddober; 16.04.2009

Вы хотите преобразовать десятичную строку в двоичную с плавающей запятой или в двоичную строку? Если первое, просто используйте valueOf(); в последнем случае используйте valueOf(), а затем toString() или printf().

person Rick Regan    schedule 17.04.2009

0,1 НЕ является двоичным представлением 0,5

Java будет представлять 0,5 с использованием IEEE 754, как указано в Спецификация языка Java. BigInteger.valueOf(Double.doubleToRawLongBits(0.5)).toByteArray() даст вам побайтовое представление 0,5, как это делает Java внутри.

person H Marcelo Morales    schedule 16.04.2009
comment
0,1 НЕ является бинарным представлением 0,5 -- Да, это так, но это не представление IEEE 754. Это не одно и то же. - person Michael Myers; 16.04.2009