在Java中将浮点数和双精度数转换为位和十六进制表示

8

如何获取doublefloat的单个位(或整个变量)?

例如,如果我有 float a = 0.5;

我期望得到一个等于"00111111000000000000000000000000"String

或者以十六进制表示为:
"F000000"


不行。为什么?因为它与http://stackoverflow.com/questions/10637594/calculating-double-neighbours-of-a-decimal-value有关。我认为如果我从二进制值中减去1,我会得到另一个值。 - Jan Ajan
3
@dcrooney问这个问题是为了知道这是否是一道作业题,因为如果是作业,我们会尽量小心回答,以免抑制你的学习 :) - kentcdodds
4个回答

14

Java中,float类型占用32位,类似于int类型,而double类型占用64位,类似于long类型。如果要找到这些数字的二进制表示,需要进行以下操作:

float a = 0.5f;
int bits = Float.floatToIntBits(a);
String.format("%32s", Integer.toBinaryString(bits)).replace(" ", "0");
String.format("%8s", Integer.toHexString(bits)).replace(" ", "0");

"00111111000000000000000000000000" 的二进制表示(32位)
"3f000000" 的十六进制表示(32位)

double a = 0.5d;
long bits = Double.doubleToLongBits(a);
String.format("%64s", Long.toBinaryString(bits)).replace(" ", "0");
String.format("%16s", Long.toHexString(bits)).replace(" ", "0");

"0011111111100000000000000000000000000000000000000000000000000000" 代表64位的二进制数字
"3fe0000000000000" 代表64位的十六进制数字

您可以通过执行反向操作来验证其是否有效:

int bits = Integer.parseInt("00111111000000000000000000000000", 2);
Float.intBitsToFloat(bits);

0.5(浮点数)

long bits = Long.parseLong("0011111111100000000000000000000000000000000000000000000000000000", 2);
Double.longBitsToDouble(bits);

0.5(双精度)

对于十六进制表示,您可以分别使用Integer.parseInt("...", 16);Long.parseLong("...", 16);


2
如果符号位为零,它将不会被打印! - math
1
@math,你能解释一下吗?你是指符号位不会被打印出来,还是整个值都不会被打印出来?如果是前者,那么是的,Long.toBinaryString不会打印多余的位数,因为"This [unsigned long] value is converted to a string of ASCII digits in binary (base 2) with no extra leading 0's",但这并不仅限于符号位。你可以从左边用零填充该值以获得所需的列宽。 - Mike Samuel
就像我说的那样,由于前导零,它不会被打印出来。当然,可以用前导零填充它,但是上面的语句可能会被误解。如果指数也有前导零,它们也将被削减。 - math
1
int bits = Float.floatToIntBits(f); System.out.println(Integer.toBinaryString(bits));这段代码能够正常运行,它可以用来查看 float 类型数值的二进制位表示。 - gherson

4

查看Float.floatToIntBits() 或 Float.floatToRawIntBits()。 这会将浮点数以int形式返回其位。 如果需要字符串形式,使用Integer.toBinaryString()

注意,如果HSB存在问题,您可能需要转换为long型以避免“溢出”。


IEEE-754浮点数中的HSB为符号位,除非它是一个NaN值,因此生成的整数的符号与浮点数相同,但有一个例外:-0.0。 - Mike Samuel
同意。那个评论是因为一些Java int <-> String代码对HSB很挑剔。例如,这个stackoverflow讨论。虽然我认为它主要用于解析字符串,而不是创建它们,所以这个问题可能不适用于这里。 - user949300

0
public void printFloatBits(float f) {
    int bits = Float.floatToIntBits(f);
    // Extract each bit from 'bits' and compare it by '0'
    for (int i=31; i>=0; --i) {
        // int mask = 1 << i;
        // int oneBit = bits & mask;
        // oneBit == 0 or 1?
        System.out.print((bits & (1 << i)) == 0 ? "0" : "1");
    }
}

-2

4
"Byte value" 的返回值相当于 (byte) myDouble,这是一种有损转换。 - Mike Samuel
3
答案错误。Float.byteValue()Double.byteValue()只是将数字强制转换为字节。 - Pacerier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接