# 如何将整数转换为带符号的十六进制补码：

go评论60阅读模式

how to convert integer to hex signed 2's complement:

# 问题

``````private String toHex(String arg, boolean isAllInt) {
String hexVal = null;
log.info("arg {}, isAllInt {}", arg, isAllInt);
if (isAllInt) {
int intVal = Integer.parseInt(arg);
hexVal = Integer.toHexString(intVal);
// 一些魔法将这个 hexVal 转换为它的二进制补码
} else {
hexVal = String.format("%040x", new BigInteger(1, arg.getBytes(StandardCharsets.UTF_8)));
}
log.info("str {} hex {}", arg, hexVal);
return hexVal;
}
``````

00216

Pretty basic stuff i am sure but bits are not my forte.

So for some internal calculation i am trying to convert a given input ( constraint is that it would be a integer string for sure) into its hex equivalent, what stumped me is on how to get
Hex signed 2's complement:

My noob code:

``````   private String toHex(String arg, boolean isAllInt) {
String hexVal = null;
log.info(&quot;arg {}, isAllInt {}&quot;, arg, isAllInt);
if (isAllInt) {
int intVal = Integer.parseInt(arg);
hexVal = Integer.toHexString(intVal);
// some magic to convert this hexVal to its 2&#39;s compliment
} else {
hexVal = String.format(&quot;%040x&quot;, new BigInteger(1, arg.getBytes(StandardCharsets.UTF_8)));
}
log.info(&quot;str {} hex {}&quot;, arg, hexVal);
return hexVal;
}
``````

Input: 00001 <br />
Output: 1<br />
Expected Output: 0001<br />

Input: 00216 <br />
Output: D8<br />
Expected Output: 00D8<br />

00216

Input: 1192633166<br />
Output: 4716234E<br />
Expected Output: 4716234E<br />

any predefined library is much welcome or any other useful pointers!

# 答案1

``````int intVal = Integer.parseInt(arg);
if (intVal >= 0 && intVal <= 0xffff) {
hexVal = String.format("%04x", intVal);
} else {
hexVal = String.format("%08x", intVal);
}
``````

So to pad the hex digits up to either 4 digits or 8 digits, do:

``````int intVal = Integer.parseInt(arg);
if (intVal &gt;= 0 &amp;&amp; intVal &lt;= 0xffff) {
hexVal = String.format(&quot;%04x&quot;, intVal);
} else {
hexVal = String.format(&quot;%08x&quot;, intVal);
}
``````

See Java documentation on how the format strings work.

# 答案2

## 二进制补码表示法

• 0 表示为 `0000 0000 0000 0000` 或十六进制 `0000`
• 1 表示为 `0000 0000 0000 0001` 或十六进制 `0001`
• 2 表示为 `0000 0000 0000 0010` 或十六进制 `0002`
• 3 表示为 `0000 0000 0000 0011` 或十六进制 `0003`
• 4 表示为 `0000 0000 0000 0100` 或十六进制 `0004`

• -1 表示为 `1111 1111 1111 1111` 或十六进制 `ffff`
• -2 表示为 `1111 1111 1111 1110` 或十六进制 `fffe`
• -3 表示为 `1111 1111 1111 1101` 或十六进制 `fffd`

> 二补数是原始值的负数的十六进制表示

## Two's Complement Representation

Two's complement is an agreement how to represent signed integral numbers in e.g. 16 bits (in olden times, different representations have been used by various processors, e.g. one's complement or sign-magnitude).

Positive numbers and zero are represented as expected:

• 0 is `0000 0000 0000 0000` or hex `0000`
• 1 is `0000 0000 0000 0001` or hex `0001`
• 2 is `0000 0000 0000 0010` or hex `0002`
• 3 is `0000 0000 0000 0011` or hex `0003`
• 4 is `0000 0000 0000 0100` or hex `0004`

Negative numbers are represented by adding `1 0000 0000 0000 0000` to them, giving:

• -1 is `1111 1111 1111 1111` or hex `ffff`
• -2 is `1111 1111 1111 1110` or hex `fffe`
• -3 is `1111 1111 1111 1101` or hex `fffd`

This is equivalent to: take the positive representation, flip all bits, and add 1.

For negative numbers, the highest bit is always 1. And that's how the machine distinguishes positive and negative numbers.

All processors in use today do their integer arithmetic based on two's complement representation, so there's typically no need to do special tricks. All the Java datatypes like `byte`, `short`, `int`, and `long` are defined to be signed numbers in two's complement representation.

In a comment you wrote

> 2's compliment is hex of negative of original value

That mixes up the concepts a bit. Two's complement is basically defined on bit patterns, and groups of 4 bits from these bit patterns can nicely be written as hex digits. Two's complement is about representing negative values as bit patterns, but from your question and comments I read that you don't expect negative values, so two's complement shouldn't concern you.

## Hex Strings

To represent signed values as hex strings, Java (and most other languages / environments) simply looks at the bit patterns, ignoring their positive / negative interpretation, meaning that e.g. -30 (`1111 1111 1110 0010`) does not get shown as "-1e" with a minus sign, but as "ffe2".

Because of this, negative values will always get translated to a string with maximum length according to the value's size (16 bits, 32 bits, 64 bits giving 4, 8, or 16 hex digits), because the highest bit will be 1, resulting in a leading hex digit surely not being zero. So for negative values, there's no need to do any padding.

Small positive values will have leading zeros in their hex representation, and Java's `toHexString()` method suppresses them, so 1 (0000 0000 0000 0001) becomes "1" and not "0001". That's why e.g. `format(&quot;%04x&quot;, ...)`, as in @nos's answer, is useful.

• 本文由 发表于 2020年10月8日 14:31:01
• 转载请务必保留本文链接：https://go.coder-hub.com/64256945.html
• hex
• java
• twos-complement
• type-conversion

go 61