Android/Kotlin數據操作byte16進制0xaa變為0xffffffaa的解決辦法


解決辦法

#kotlin
Integer.toHexString(itm.toInt() and(0xff))
#java
Integer.toHexString(itm.toInt() & 0xff)

以下為引用內容,方便查閱

引自https://www.cnblogs.com/cvbaka/archive/2004/01/13/4747337.html

這是因為Integer.toHexString()的接收參數是int,不是byte,於是運算是會先把byte強制轉換為int

由於java中強制轉換是保持值不變,而在計算機中數都是用補碼表示的,java中int是32位4個byte, 正數補碼是正數本身,這樣不會有問題,強轉為32位時前面24位會填充0,

而負數的補碼是"將其對應正數二進制表示所有位取反(包括符號位,0變1,1變0)后加1",

於是32位的0x00 00 00 80(0000 ... 0000 1000 0000)補碼是0xFF FF FF 80(1111 ... 1111 1000 0000),前面是填充的1

所以Integer.toHexString()后就會變成前面多了一串F


引自https://blog.csdn.net/Jamie_Jiang/article/details/78343549?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

今天學到一句Integer.toHexString(b & 0xff)(b是byte類型的)

馬克一下什么意思

Integer.toHexString這個方法是把字節(轉換成了int)以16進制的方式顯示。

首先,

以下是java.lang.Integer.toHexString()方法的聲明

public static String toHexString(int i)

其次,

&是什么

&是位操作符,“按位與”當&作為位運算時,1&1=1 ,1&0=0,0&0=0

舉個栗子: a=1;b=2;a&b=0

計算方法為:

1轉成二進制 01

2轉成二進制 10

所以,a&b=00 轉成十進制為0

然后,

0xff是什么

0x表示是十六進制。

ff是兩個十六進制的數,每個f用二進制表示是1111,所以占四位(bit),兩個f(ff)占八位(bit),八位(bit)也就是一個字節(byte).

最后,

上面的這些都理解了,那么具體是怎么個流程呢?

首先toHexString傳的參數應該是int類型32位,此處傳的是byte類型8位,所以前面需要補24個0。然后& 0xff 就是把前面24個0去掉只要后8位。

(經過百度)int本身就是由4組byte組成,並且Java中本身就以byte讀取。所以此處傳參沒有問題。

toHexString(b & 0xff)相當於做了一次位的與運算,將前24位字符省略,將后8位保留。即只轉了后8位。即可得到兩個十六進制的值。

我的理解是這樣,如有不對歡迎指正!也可補充!


引自https://blog.csdn.net/u010428110/article/details/106824749/

一、位操作:

shl(bits) – 左移位 (Java’s <<)

shr(bits) – 右移位 (Java’s >>)

ushr(bits) – 無符號右移位 (Java’s >>>)

and(bits) – 與 &

or(bits) – 或 ||

xor(bits) – 異或

inv() – 反向

    val a = 5
    val b = a shl 2 //左移2位,5*2*2=20
    println(b)  //20

二、位運算符:

運算符 表示含義

and(bits) 按位與

or(bits) 按位或

inv(bits) 按位非

xor(bits) 按位異或

shl(bits) 左移運算符

shr(bits) 右移運算符

ushr(bits) 無符號右移運算符

三、Kotlin的位運算符只能對Int和Long兩種數據類型起作用。

四、位操作和位運算實例

通過位運算來保證頭尾不超過數組范圍,通過位操作來擴容(數組長度保持為2的整數倍,方便進行位運算)

//如ArrayDeque通過位與運算(等價於java中的'&'),保證頭尾不超過數組邊界
class SimpleIntArrayDeque {
    private var elements: Array<Int?> = arrayOfNulls(16) //擴容數組
    private var head: Int = 0 //頭
    private var tail: Int = elements.size //尾,tail-1是當前最后一位數據
 
    fun addFirst(value: Int) {
        if (value == null)
            throw NullPointerException()
        //當head-1為-1時,實際上是11111111&00111111,結果是00111111,也就是物理數組的尾部15;
        head = (head - 1) and (elements.size - 1)
        elements[head] = value
        if (head == tail)
            doubleCapacity()
    }
 
    fun addLast(value: Int) {
        if (value == null)
            throw NullPointerException()
        elements[tail] = value
        //當tail+1為16時,實際上是01000000&00111111,結果是00000000,也就是物理數組的頭部0;
        tail = (tail + 1) and (elements.size - 1)
        if (tail == head)
            doubleCapacity()
    }
    
    fun pollFirst(): Int? {
        val h = head
        val result = elements[h]
        if (result != null) {
            elements[h] = null
            head = (h + 1) and (elements.size - 1)
        }
        return result
    }
    
    fun pollLast(): Int? {
        val t = (tail - 1) and (elements.size - 1)
        val result = elements[t]
        if (result != null) {
            elements[t] = null
            tail = t
        }
        return result
    }
 
    //擴容:插入數據前,判斷插入后將頭尾相等(即插入后數組將填滿),則立即擴容
    private fun doubleCapacity() {
        val p = head
        val n = elements.size
        val r = n - p
        var newCapacity = n shl 1  //擴容2倍
        if (newCapacity < 0)
            throw IllegalArgumentException("Sorry, deque too big")
        var newElements: Array<Int?> = arrayOfNulls(newCapacity)
        //從頭部開始拷貝,拷貝頭部以后的所有內容,並把頭部位置重置為0
        System.arraycopy(elements, p, newElements, 0, r)
        /**
         * 從0開始拷貝,拷貝頭部之前的內容,並把拷貝內容接上剛才拷貝的位置,
         * 使得原來的數組放到新數組的前半部分
         */
        System.arraycopy(elements, 0, newElements, r, p)
        //釋放舊的數組內存
        Arrays.fill(elements, null)
        elements = newElements
        head = 0
        tail = n
    }
    
    fun size(): Int {  //插入前判斷,若插入后占滿則立即擴容,因此size不會大於數組長度減一
        return (tail - head) and (elements.size - 1)
    }
    
    fun isEmpty(): Boolean {
        return head == tail
    }
 
    fun peekFirst(): Int? {
        return elements[head]
    }
 
    fun peekLast(): Int? {
        return elements[(tail -1) and (elements.size - 1)]
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM