在 Stack Overflow 上,已經有人回答了將二進制整數轉換為二進制補碼的問題。無論如何,我沒有找到任何令人滿意的答案,因為他們沒有考慮預先確定的位數。此外,我在 Stack Overflow 上找到的代碼會使終端崩潰或給出大量奇怪的錯誤。
由于這些原因,我從頭開始重寫了以下 Bash 函式,它似乎完成了我希望正確給出的任務。為了清楚起見,我對代碼進行了評論。
如您所見,我故意在以下行中生成一個溢位:x=$((2**($bits-1)-$x));
我的問題是這段代碼在 Bash 中是否總是可靠的,因為在其他語言中,溢位是一種錯誤情況;但是,在這里,我使用它來獲得所需的結果。
# Given a decimal number, prints its two's complement with the number of bits used by Bash
twos() {
x=$1; # input number in base 10
msb="0"; # the "most significant bit" is 0 for positive integers, 1 for negative integers
bits=$(getconf LONG_BIT); # detect the machine architecture, 32bit or 64bit
if [ "$x" -lt 0 ]; then
# the input number $x is negative
x=$((2**($bits-1)-$x)); # 2^(bits-1)-1 is the max integer number, -$x is positive, so it's an overflow
msb="1"; # "most significant bit" of negative numbers
fi
out=$(echo "obase=2;$x" | bc | tr -dc '0-9'); # conversion of $x to binary base, any sign is removed
n=$(($bits-1-${#out})); # number of zeros to add
if [ "$n" -gt 0 ]; then
zeros=$(printf '%0.s0' $(seq 1 $n)); # string consisting only of zeros
else
zeros=""; # deletes the variable that may be left in memory from a previous function call
fi
echo $msb$zeros$out; # prints the two's complement
}
一些例子:
$ twos 0
0000000000000000000000000000000000000000000000000000000000000000
$ twos 1
0000000000000000000000000000000000000000000000000000000000000001
$ twos 2
0000000000000000000000000000000000000000000000000000000000000010
$ twos 100
0000000000000000000000000000000000000000000000000000000001100100
$ twos -1
1111111111111111111111111111111111111111111111111111111111111111
$ twos -2
1111111111111111111111111111111111111111111111111111111111111110
$ twos -100
1111111111111111111111111111111111111111111111111111111110011100
$ twos 9223372036854775807
0111111111111111111111111111111111111111111111111111111111111111
$ twos -9223372036854775808
1000000000000000000000000000000000000000000000000000000000000000
uj5u.com熱心網友回復:
簡單一點:
twos() {
n=$(getconf LONG_BIT)
printf 'obase=2; 2^%d %d\n' "$n" "$1" | bc | sed -E "s/.*(.{$n})$/\1/"
}
twos 100
0000000000000000000000000000000000000000000000000000000001100100
這只是用于bc添加2^n(其中n是 32 或 64),以 2 為基數列印并僅保留n最低有效位。
請注意,從技術上講,數字的二進制補碼是相反的。因此,您要尋找的更多的是二進制補碼中數字的二進制表示。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/493702.html
標籤:重击
