Lua 位和字節

一、位運算

從 Lua 5.3 版本開始,提供了針對數值類型的一組標準位運算符,與算數運算符不同的是,運算符只能用于整型數。

運算符描述
&按位與
|按位或
按位異或
>>邏輯右移
<<邏輯左移
~(一元運算)按位取反

位的使用,可以參考小盆友的另一篇文章 《android位運算簡單講解》
https://blog.csdn.net/weixin_37625173/article/details/83796580

print(string.format("%x", 0xff & 0xabcd))       --> cd
print(string.format("%x", 0xff | 0xabcd))       --> abff
print(string.format("%x", 0xff ~ 0xabcd))       --> ab32
print(string.format("%x", ~0))                  --> ffffffffffffffff (16 個 6,每一個十六進制 4 位,剛好是 64 位)
print(string.format("%x", 0xff << 12))          --> ff000
print(string.format("%x", 0xff >> -12))         --> ff000
-- 移位數等于或大于整型表示的位數,由于所有的位都被移出,則結果為 0
print(string.format("%x", -1 << 80))            --> 0

1-1、注意小點

所有的位運算針對一個整數型的所有位。

Lua 的兩個移位操作都會用 0 填充空出的位,這種行為稱為邏輯移位。 Lua 中沒有提供算術右移(即使用符號位填充空出的位),但是可以通過向下取整除法( floor 除法)達到算數右移

local data = -0x100
print("邏輯右移:", string.format("%x >> 1 --> %x", data, data >> 1))    --> 邏輯右移:	ffffffffffffff00 >> 1 --> 7fffffffffffff80
-- 達到算數右移一位,2^n ( n 即為右移位數)
print("算數右移:", string.format("%x >> 1 --> %x", data, data // 2))    --> 算數右移:	ffffffffffffff00 >> 1 --> ffffffffffffff80

移位數是負數則表示向相反方向移位。a>>na<<-n 相等。

二、無符號整型數

在有符號整型數中使用一個比特位來存儲符號位。所以 64 的整型數中最大可以表示為 2^63-1 ,而不是 2^64-1 。

值得注意的是 Lua 語言不顯示支持無符號整型數, 但這并不妨礙我們在 Lua 中使用無符號整型這一特性,只是在使用過程中需要注意一些細節。

2-1、細節一:打印無符號整數

對于一個數最直觀的就是展示出來,所以我們可以使用 string.format 進行格式化數值, 使用 %u(無符號整數)或 %X (十六進制)進行展示,這樣就能很直觀的感知無符號整數每一位的數值是多少。如果直接將無符號整數打印,會被認為是有符號整數,就不利于閱讀。

local x = 3 << 62
print("有符號整數顯示:", x)        --> 有符號整數顯示:	-4611686018427387904
print("使用十進制無符號顯示", string.format("%u", x))       --> 使用十進制無符號顯示	13835058055282163712
print("使用十六進制無符號顯示", string.format("0x%X", x))   --> 使用十六進制無符號顯示	0xC000000000000000

2-2、細節二:無符號整數,加減乘運算

對于無符號整數的加減乘運算,和有符號是一樣的,只是要注意溢出

local x = 3 << 62
print("使用十進制無符號顯示", string.format("%u", x))                   --> 使用十進制無符號顯示	13835058055282163712
print("使用十進制無符號顯示 +1", string.format("%u", x + 1))            --> 使用十進制無符號顯示 +1	13835058055282163713
print("使用十進制無符號顯示 -1", string.format("%u", x - 1))            --> 使用十進制無符號顯示 -1	13835058055282163711
x = 1 << 62
print("使用十六進制無符號顯示", string.format("0x%X", x))               --> 使用十六進制無符號顯示	    0x4000000000000000
print("使用十進制無符號顯示 * 2", string.format("%X", x * 2))           --> 使用十進制無符號顯示 * 2	0x8000000000000000

2-3、細節三:無符號整數,除法運算

對于無符號整數的除法會有些不一樣,需要注意其符號位的影響,可以通過下面函數進行無符號整數的除法(細節也在每一行的注釋中)

function udiv(n, d)-- d<0 實質比較除數是否大于 2^63if d < 0 then-- 如果除數大于被除數(n<d),則商為 0 ;否則為 1if math.ult(n, d) thenreturn 0elsereturn 1endend-- n >> 1 等價于將無符號整數 n / 2 , 這樣的做法是先去除符號位置的影響-- 最后 << 1 等價于 * 2 ,這樣是為了糾正一開始 >> 1-- // d 進行有符號整數的正常向下取整除法local q = ((n >> 1) // d) << 1-- 計算因為移位和向下取整導致的丟失數值,計算出兩個結果后,如果偏差大于除數,說明需要加一local r = n - q * dif not math.ult(r, d) thenq = q + 1endreturn q
endlocal u1 = 1 << 1
-- 正常數字除法
local div1 = 2
print(string.format("%X/%X = %X", u1, div1, udiv(u1, div1)))        --> 2/2 = 1
-- (符號位為 1 )很大的數進行無符號除法
local u2 = 1 << 63
print(string.format("%X/%X = %X", u2, div1, udiv(u2, div1)))        --> 8000000000000000/2 = 4000000000000000 
-- (符號位為 0 )正常的數進行無符號除法
local u3 = 1 << 62
print(string.format("%X/%X = %X", u3, div1, udiv(u3, div1)))        --> 4000000000000000/2 = 2000000000000000
-- 除數很大,符號為為 1 ,被除數 < 除數
local div2 = 1 << 63
print(string.format("%X/%X = %X", u3, div2, udiv(u3, div2)))        --> 4000000000000000/8000000000000000 = 0
-- 被除數 > 除數
local u4 = (1 << 63) + 1
print(string.format("%X/%X = %X", u4, div2, udiv(u4, div2)))        --> 8000000000000001/8000000000000000 = 1
local u5 = (1 << 63) + 3
print(string.format("%X/%X = %X", u5, div1, udiv(u5, div1)))        --> 8000000000000003/2 = 4000000000000001

2-4、細節四:無符號整數比較

如果直接將無符號整數進行比較,則會導致一種情況:因為第 64 位在有符號整數是符號位,而無符號整數則用于正常表示數值,所以當第 64 位為 1 時,則會導致在直接比較時(此時被當作是有符號整數)無符號越大的值反而越小。

解決此類方法有兩種方式:

第一種,使用 math.ult 進行比較無符號整數

local n1 = 0x7fffffffffffffff
local n2 = 0x8000000000000000
print(n1, n2, n1 < n2)              --> 9223372036854775807	-9223372036854775808	false
print(n1, n2, math.ult(n1, n2))     --> 9223372036854775807	-9223372036854775808	true

第二種,在進行有符號比較前先用掩碼去兩個操作數的符號位

local n3 = -10
local n4 = 10
local mask = 0x8000000000000000
print("有符號:", n3, "<", n4, n3 < n4)                     --> 有符號:	-10<10	true
print("無符號:", n4, "<", n3, math.ult(n4, n3))            --> 無符號:	10<-10	true
print("無符號:", n4, "<", n3, (n4 ~ mask) < (n3 ~ mask))   --> 無符號:	10<-10	true

2-5、細節五:整型數和浮點數互轉

整型轉浮點數

local u = 0xC000000000000000
print(math.type(u), string.format("%X", u))         --> integer	C000000000000000
-- + 0.0 是為將 u 轉為 float , % 取余的規則符合通用規則,只要其中有一個為浮點數,結果則為浮點數
-- %(2 ^ 64) 是為將結果約束在這其中,否則顯示時會被認為是有符號
local f = (u + 0.0) % 2 ^ 64
print(math.type(f), string.format("%.0f", f))       --> float	13835058055282163712
local f1 = (u + 0.0)
print(math.type(f1), string.format("%.0f", f1))     --> float	-4611686018427387904

浮點數轉整型

function utointerger(value)if math.type(value) == "integer" thenreturn valueend-- f + 2 ^ 63 是為了讓數轉為一個大于 2 ^ 64 的數-- % (2 ^ 64) 是為了讓數值限制在 [0, 2 ^ 64) 范圍-- - 2 ^ 63 是為了把結果改為一個"負值"(最高位為 1 )-- 對于小于 2 ^ 63 的數:-- 其實沒有什么特殊的,加完一個數值(2 ^ 63)之后有減掉了,所以沒有什么特殊local result = math.tointeger(((value + 2 ^ 63) % (2 ^ 64)) - 2 ^ 63)return result + (math.tointeger(value - result) or 0)
endlocal f = 0xF000000000000000.0
local u = utointerger(f)
print(math.type(u), string.format("%X", u))     --> integer	F000000000000000

值得注意:

因為這里是一個浮點數的計算,在我們之前的分享浮點數的文章中,有講到 在 [-2^53, 2^53] 范圍內,只需要將 整型數值 + 0.0 則可以進行轉換為 浮點數,如果超出范圍,會導致精度丟失,取近似值。

所以上述代碼的 f 值如果超出這一范圍,低位數可能會有問題

local f1 = 0x8000000000000001.0
local u1 = utointerger(f1)
print(math.type(u1), string.format("%X", u1))       --> integer	8000000000000000

三、二進制數據

Lua 從 5.3 開始提供了對二進制數和基本類型值之間進行轉換的函數。

string.pack 會把值 “打包” 為二進制字符串

string.unpack 則從字符串中提取二進制

3-1、string.pack(fmt, v1, v2, …)

按照 fmt 格式將 v1、v2 進行打包為二進制字符串

參數:

  • fmt:打包格式
  • v1、v2:需要打包的數據

返回值:

字符串類型,即打包后的二進制數據

local format = "iii"
local s = string.pack(format, 3, -27, 450)
print(s, #s)        --> �����	12

3-2、string.unpack(fmt, s, pos)

按照 fmt 格式對字符串 s 偏移了 pos 個位置后,進行解析

參數:

  • fmt:解析格式
  • s:需要解析的字符串
  • pos:可選,從字符串 s 的第 pos 個位置開始解析,默認為 1

返回值:

會有兩個返回值,第一個為解析后的內容,第二個為解析的字符串 s 中最后一個讀取的元素在字符串中的位置。

local format = "iii"
local s = string.pack(format, 3, -27, 450)  --> �����	12
-- 最后的 13 即,最后一個讀取的元素位置
print(string.unpack(format, s))             --> 3	-27	450	13

3-3、整型數格式可選參數

每種選項對應一種類型大小

格式描述
bchar
hshort
iint(可以跟一個數字,表示多少字節的整型數)
llong
jLua 語言中的整型數大小

3-3-1、固定字節

在使用 i 的時候,大小會與機器有關,如果想要達到固定大小,可以考慮在后面加上數字(1~16),類似 i8,則會產生 8 個字節的整型數。

local n1 = 1 << 54
print(string.format("%X", n1))          --> 40000000000000
local x1 = string.pack("i8", n1)
print(#x1, string.format("%X", string.unpack("i8", x1)))    --> 8	40000000000000

3-3-2、打包和解包都會檢測溢出

打包的時候,如果發現字節不夠裝數值,則會拋出異常 bad argument #2 to 'pack' (integer overflow)

local x2 = string.pack("i8", 1 << 63)
print(string.format("%X", string.unpack("i8", x2)))-- 打包會進行檢查是否溢出
-- bad argument #2 to 'pack' (integer overflow)
print(string.pack("i7", 1 << 63))

解包也是一樣的,會拋出異常 12-byte integer does not fit into Lua Integer ,因為對于 Lua 的整型數是 8 字節。

local x = string.pack("i12", 2 ^ 61)
print(string.unpack("i12", x))
x = "aaaa" .. "aaaa" .. "aaaa"
-- 解包也會檢查是否能裝得下
-- 12-byte integer does not fit into Lua Integer
--string.unpack("i12", x)

3-3-3、格式化無符號

每一個格式化選項都有一個大寫的版本,對應無符號整型數:

local s = "\xFF"
print(string.unpack("b", s))        --> -1	2
print(string.unpack("B", s))        --> 255	2

3-4、字符串格式可選參數

可以使用三種形式打包字符串

格式描述
z\0 結尾的字符串
cn定長字符串,n 是被打包字符串的字節數
sn顯式長度字符串,會在存儲字符串前加上該字符串的長度,n 是用于保存字符串長度的無符號整型數的大小

舉些例子

s1 表示將字符串長度保存在一個字節中

print("----- sn -----")
local s1 = string.pack("s1", "hello")
print("s1 長度", #s1)
for i = 1, #s1 doprint(string.unpack("B", s1, i))
end--> s1 長度	6
--> 5	2   (length)
--> 104	3   ('h')
--> 101	4   ('e')
--> 108	5   ('l')
--> 108	6   ('l')
--> 111	7   ('o')

s2 則表示用兩個字節存儲

s1 = string.pack("s2", "hello")
print("s2 長度", #s1)
for i = 1, #s1 doprint(string.unpack("B", s1, i))
end--> s2 長度	7
--> 5	2   (length)
--> 0	3   (length)
--> 104	4   ('h')
--> 101	5   ('e')
--> 108	6   ('l')
--> 108	7   ('l')
--> 111	8   ('o')

值得注意,如果保存長度的字節容納不下字符串的長度,則會有拋出異常

當然也可以直接使用 s 進行打包字符串,會使用 size_t 類型進行保存,在 64 位的機子上,一般使用 8 個字節保存,大多數情況這會有些浪費。

s1 = string.pack("s", "hello")
print("s 長度", #s1)
print(string.unpack("s", s1, i))
for i = 1, #s1 doprint(string.unpack("B", s1, i))
end--> s 長度	13
--> hello	14
--> 5	2   (length)
--> 0	3   (length)
--> 0	4   (length)
--> 0	5   (length)
--> 0	6   (length)
--> 0	7   (length)
--> 0	8   (length)
--> 0	9   (length)
--> 104	10  ('h')
--> 101	11  ('e')
--> 108	12  ('l')
--> 108	13  ('l')
--> 111	14  ('o')

cn 打包固定長度自負串

-- 因為這里每個中文占 3 個字節,所以是 c9 ,后面打印也就有九行
local name = "江澎涌"
local fmt = string.format("c%d", #name)
local s3 = string.pack(fmt, name)
for i = 1, #s3 doprint(string.unpack("B", s3, i))
end
print(string.unpack(fmt, s3))--> 230	2
--> 177	3
--> 159	4
--> 230	5
--> 190	6
--> 142	7
--> 230	8
--> 182	9
--> 140	10
--> 江澎涌	10

3-5、浮點數格式可選參數

格式描述
f單精度浮點數
d雙精度浮點數
nLua 語言浮點數
local p = string.pack("fdn", 3.14, 1.70, 10.89)
print(string.unpack("fdn", p))                  --> 3.1400001049042	1.7	10.89	21

3-6、大小端模式

默認情況下,格式使用的是機器原生的大小端模式。可以在格式中使用,一旦使用,后續的都會作用

格式描述
>大端模式、網絡字節序
<小端模式
=改回機器默認模式

大端模式

local s1 = string.pack(">i2 i2", 500, 24)
for i = 1, #s1 doprint(string.unpack("B", s1, i))
end--> 1	2
--> 244	3
--> 0	4
--> 24	5

小端模式

local s2 = string.pack("<i2 i2", 500, 24)
for i = 1, #s2 doprint(string.unpack("B", s2, i))
end--> 244	2
--> 1	3
--> 24	4
--> 0	5

一圖勝千言

改回默認

local s3 = string.pack(">i2 =i2", 500, 24)
for i = 1, #s3 doprint(string.unpack("B", s3, i))
end--> 1	2
--> 244	3
--> 24	4
--> 0	5

3-7、對齊數據

使用 !n 進行強制數據對齊到 n 為倍數的索引上。如果只是使用 ! 則會使用機器默認對其方式

如果數據比 n 小,則對其到其自身大小,否則對其到 n 上。

例如 !4 ,則 1 字節整型數會被寫入以 1 位倍數的所以位置上,2 字節的整型數會被寫入到以 2 為倍數的索引位置上,而 4 字節或更大的整型數會被寫入到以 4 為倍數的索引位置上。

local s = string.pack("!4 i1 i2 i4", 10, 10, 10)
print("#s", #s)
for i = 1, #s doprint(string.unpack("i1", s, i))
end--> #s	8
--> 10	2
--> 0	3
--> 10	4
--> 0	5
--> 10	6
--> 0	7
--> 0	8
--> 0	9

string.pack 通過補 0 的形式實現對齊。string.unpack 則會在讀取字符串時簡單的跳過這些補位。

對齊只對 2 的整數次冪有效,如果不是則會報錯 format asks for alignment not power of 2

在所有的格式化字符串默認的都會帶有前綴 =!1,即表示使用默認的大小端模式且不對齊。

3-8、手工添加補位

可以通過 x 進行 1 字節的補位,string.pack 會在結果字符串中增加一個 0 字節,string.unpack 則會從目標字符串中跳過這一字節

local s = string.pack("i1i1xi1", 10, 10, 10)
print("#s", #s)
for i = 1, #s doprint(string.unpack("i1", s, i))
end--> #s	4
--> 10	2
--> 10	3
--> 0	4
--> 10	5

四、拓展一下

可以使用這一節的內容實現一些類似二進制文件查看器的功能,如下圖所示

具體代碼 https://github.com/zincPower/lua_study_2022/blob/master/7%20%E4%BD%8D%E5%92%8C%E5%AD%97%E8%8A%82/dump.lua

還可以對圖片進行操作,具體可以看 https://github.com/zincPower/lua_study_2022/blob/master/7%20%E4%BD%8D%E5%92%8C%E5%AD%97%E8%8A%82/writeBinary.lua

五、寫在最后

Lua 項目地址:Github傳送門 (如果對你有所幫助或喜歡的話,賞個star吧,碼字不易,請多多支持)

如果覺得本篇博文對你有所啟發或是解決了困惑,點個贊或關注我呀

公眾號搜索 “江澎涌”,更多優質文章會第一時間分享與你。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/40852.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/40852.shtml
英文地址,請注明出處:http://en.pswp.cn/news/40852.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Git 如何使用TortoiseGit 操作本地倉庫

初始化倉庫 方法一: 新建一個文件夾,進入文件夾內部操作 1、右鍵--> 在這里創建Git 版本庫 注意: 不要直接在桌面上操作,否則桌面就是一個倉庫 方法二: 1、右鍵-->Git GUI here 方法三: 命令行模式 1、 git init 創建完畢倉庫,我們發現,此時我們創建的文件夾下…

leetcode做題筆記83刪除排序鏈表中的重復元素

給定一個已排序的鏈表的頭 head &#xff0c; 刪除所有重復的元素&#xff0c;使每個元素只出現一次 。返回 已排序的鏈表 。 輸入&#xff1a;head [1,1,2] 輸出&#xff1a;[1,2] 思路一&#xff1a;模擬題意 struct ListNode* deleteDuplicates(struct ListNode* head){i…

FreeRTOS qemu mps2-an385 bsp 移植制作 :系統運行篇

相關文章 FreeRTOS qemu mps2-an385 bsp 移植制作 &#xff1a;環境搭建篇 FreeRTOS qemu mps2-an385 bsp 移植制作 &#xff1a;系統啟動篇 開發環境 Win10 64位 VS Code&#xff0c;ssh 遠程連接 ubuntu VMware Workstation Pro 16 Ubuntu 20.04 FreeRTOSv202212.01&a…

React 全棧體系(二)

第二章 React面向組件編程 一、基本理解和使用 1. 使用React開發者工具調試 2. 效果 2.1 函數式組件 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>1_函數式組件</title> </head> &l…

計算機競賽 python 爬蟲與協同過濾的新聞推薦系統

1 前言 &#x1f525; 優質競賽項目系列&#xff0c;今天要分享的是 &#x1f6a9; python 爬蟲與協同過濾的新聞推薦系統 &#x1f947;學長這里給一個題目綜合評分(每項滿分5分) 難度系數&#xff1a;3分工作量&#xff1a;3分創新點&#xff1a;4分 該項目較為新穎&…

軟件壓力測試對軟件產品起到什么作用?

一、軟件壓力測試是什么? 軟件壓力測試是一種通過模擬正常使用環境中可能出現的大量用戶和大數據量的情況&#xff0c;來評估軟件系統在壓力下的穩定性和性能表現的測試方法。在軟件開發過程中&#xff0c;經常會遇到一些性能瓶頸和穩定性問題&#xff0c;而軟件壓力測試的作…

react-codemirror2 編輯器需點擊一下或者延時才顯示數據的問題

現象&#xff1a; <Codemirror/>組件的數據已經賦上值的情況下&#xff0c;初始狀態不渲染數據&#xff0c;需要點擊編輯框獲取焦點后才展示&#xff0c;或者延遲了幾秒才顯示出來。 原因&#xff1a; 指定了一些依賴的版本&#xff0c;可能不兼容了一些功能&#xff0c…

C# int ? 關鍵字使用方法

使用C#的時間也不算短。 但是今天看到了一個從來沒有見過的寫法 Int &#xff1f;這是個什么寫法&#xff0c;沒見過啊&#xff0c;百度了查一下&#xff0c;也在這里記錄一下。 1、int? 關鍵字說明 (1)、int? 表示一個int類型,且該int類型可空,如果不加?的話,那么int類…

C語言刷題指南(一)

&#x1f4d9;作者簡介&#xff1a; 清水加冰&#xff0c;目前大二在讀&#xff0c;正在學習C/C、Python、操作系統、數據庫等。 &#x1f4d8;相關專欄&#xff1a;C語言初階、C語言進階、數據結構刷題訓練營、有感興趣的可以看一看。 歡迎點贊 &#x1f44d; 收藏 ?留言 &am…

認識excel篇3之數據的有效性(數據驗證)

數據有效性不僅能夠對單元格的輸入數據進行條件限制&#xff0c;還可以在單元格中創建下拉列表菜單方便用戶選擇輸入。如果沒有做數據驗證&#xff0c;單元格內默認可以輸入任意類型的數據。數據驗證就是限制單元格輸入數據&#xff08;必須輸入符合要求的才能輸入&#xff09;…

VS2022如何查看類成員都在哪里被調用了(VS如何打開Call Hierarchy視圖)

文章目錄 打開Call Hierarchy視圖查看成員的調用 打開Call Hierarchy視圖 單擊菜單欄的“視圖” > “調用層次結構”&#xff0c;即可打卡Call Hierarchy視圖。 查看成員的調用 在代碼編輯窗口&#xff0c;右鍵單擊想要查看的類成員&#xff0c;然后選擇“查看調用層次結…

機器學習算法之-邏輯回歸(2)

為什么需要邏輯回歸 擬合效果太好 特征與標簽之間的線性關系極強的數據&#xff0c;比如金融領域中的 信用卡欺詐&#xff0c;評分卡制作&#xff0c;電商中的營銷預測等等相關的數據&#xff0c;都是邏輯回歸的強項。雖然現在有了梯度提升樹GDBT&#xff0c;比邏輯回歸效果更…

一、數學建模之線性規劃篇

1.定義 2.例題 3.使用軟件及解題 一、定義 1.線性規劃&#xff08;Linear Programming&#xff0c;簡稱LP&#xff09;是一種數學優化技術&#xff0c;線性規劃作為運籌學的一個重要分支&#xff0c;專門研究在給定一組線性約束條件下&#xff0c;如何找到一個最優的決策&…

JavaScript請求數據的4種方法總結(Ajax、fetch、jQuery、axios)

JavaScript請求數據有4種主流方式&#xff0c;分別是Ajax、fetch、jQuery和axios。 一、Ajax、fetch、jQuery和axios的詳細解釋&#xff1a; 1、 Ajax Ajax&#xff08;Asynchronous JavaScript and XML&#xff09;是一種使用JavaScript在用戶的瀏覽器上發送請求的技術&…

springboot綜合案例第三課

SpringSecurity入門 什么是SpringSecurity Spring Security 的前身是 Acegi Security &#xff0c;是 Spring 項目組中用來提供安全認證服務的框架。 (https://projects.spring.io/spring-security/) Spring Security 為基于J2EE企業應用軟件提供了全面安全服務。特別 是使…

環形隊列+DMA空閑中斷+接收串口數據

環形隊列DMA空閑中斷接收串口數據 一.序言二.實驗原理三.實戰是檢驗真理的唯一標準3.1 usart1.c3.2 串口中斷 三.隊列代碼4.1 fifo.c4.2 fifo.h 五.結語 一.序言 本次實驗利用環形隊列DMA空閑中斷串口。。通過這個實驗可以非常深入的理解隊列&#xff0c;DMA,串口的知識。如果…

使用低版本vcpkg時,bootstrap-vcpkg.bat無法生成vcpkg.exe的可能原因

緣由 需要使用vcpkg中低版本的第三方庫&#xff0c;下載vcpkg后&#xff0c;回退至指定版本&#xff0c;運行bootstrap-vcpkg.bat生成vcpkg.exe時&#xff0c;命令行窗口總是一閃而過&#xff0c;但是vcpkg.exe卻沒有生成。 添加pause&#xff0c;查看錯誤 編輯bootstrap-vc…

docker的網絡模式

docker0網絡 docker容器的 虛擬網關loopback &#xff1a;回環網卡、TCP/IP網卡是否生效virtual bridge&#xff1a;linux 自身繼承了一個虛擬化功能&#xff08;kvm架構&#xff09;&#xff0c;是原生架構的一個虛擬化平臺&#xff0c;安裝了一個虛擬化平臺之后就會系統就會自…

ftp設置空閑連接超時時間和數據連接超時時間

在FTP協議中&#xff0c;可以通過配置服務器端的空閑連接超時時間來設置連接的過期時間。具體步驟如下&#xff1a; 登錄FTP服務器&#xff0c;進入服務器的配置文件目錄。通常配置文件位于/etc或/etc/vsftpd目錄下。打開FTP服務器的配置文件&#xff0c;例如vsftpd.conf。在配…

區間預測 | MATLAB實現QRBiLSTM雙向長短期記憶神經網絡分位數回歸時間序列區間預測

區間預測 | MATLAB實現QRBiLSTM雙向長短期記憶神經網絡分位數回歸時間序列區間預測 目錄 區間預測 | MATLAB實現QRBiLSTM雙向長短期記憶神經網絡分位數回歸時間序列區間預測效果一覽基本介紹模型描述程序設計參考資料 效果一覽 基本介紹 區間預測 | MATLAB實現QRBiLSTM雙向長短…