本帖最后由 DEATHTOUCH 于 2023-3-9 00:24 编辑
24位整数看起来奇奇怪怪对吧,一般我们遇到的整数都是8、16、32、64位的
但是在有些地方依然需要用到24位整数,比如PCM编码的24位WAV音频文件
然而24位整数的运算十分不方便,一般我们把他转换到32位整数再继续运算
于是乎我在网上寻找各种算法,包括Delphi的,C++的,发现其效率并不高
所以我就自己撸了一些代码,并进行各种优化,最后利用语言特性找到了一种高效率转换方法
由于较新的Delphi和Free Pascal支持运算符重载,所以我们就利用这一特性
代码如下
[Delphi] 纯文本查看 复制代码 type
Int24 = record
data: array [0 .. 2] of byte;
class operator Implicit(i32: Integer): Int24;
class operator Implicit(i24: Int24): Integer;
end;
class operator Int24.Implicit(i32: Integer): Int24;
var
i24b3: array [0 .. 2] of byte absolute Result;
i32b3: array [0 .. 2] of byte absolute i32;
i24w: Word absolute Result;
i32w: Word absolute i32;
begin
i24w := i32w;
i24b3[2] := i32b3[2];
end;
class operator Int24.Implicit(i24: Int24): Integer;
var
i24b3: array [0 .. 2] of byte absolute i24;
i32b4: array [0 .. 3] of byte absolute Result;
i24w: Word absolute i24;
i32w: Word absolute Result;
begin
i32w := i24w;
i32b4[2] := i24b3[2];
if (i24b3[2] and $80 = $80) then
i32b4[3] := $FF
else
i32b4[3] := 0;
end;
如果有用Free Pascal的同学,可以不用record类型直接运算符重载
[Pascal] 纯文本查看 复制代码 type
Int24 = array[0..2] of byte;
operator:=(i32:Integer)i24:Int24;
var
i24b3:array[0..2] of Byte absolute i24;
i32b3:array[0..2] of Byte absolute i32;
i24w:Word absolute i24;
i32w:Word absolute i32;
begin
i24w:=i32w;
i24b3[2]:=i32b3[2];
end;
operator := (i24: Int24)i32: integer;
var
i24b3:array[0..2] of Byte absolute i24;
i32b4:array[0..3] of Byte absolute i32;
i24w:Word absolute i24;
i32w:Word absolute i32;
begin
i32w := i24w;
i32b4[2] := i24b3[2];
if (i24b3[2] and $80=$80) then
i32b4[3] := $ff
else
i32b4[3] := 0;
end;
在这两个功能的基础上,剩下加减乘除就是简简单单的了。
有问题或者有更优算法的欢迎提出。
|