-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLuaPlatformBitOperationLib.lua
150 lines (143 loc) · 3.47 KB
/
LuaPlatformBitOperationLib.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
local _M = {};
local math_modf = math.modf;
local archIntBits;
if math.maxinteger then --给我最大了那我直接算了
archIntBits = math.modf(math.log(math.maxinteger, 2) + 1);
else --没有最大整数,那就测试当前双精度浮点数整数精度(同样适用于luaInteger和luaNumber两种类型)
archIntBits = 53;
local i = 1;
for j = 1, 128 do --标准C定义最大的整数位数没有超过128的
i = i * 2;
if i < 0 then --负数了,说明整数溢出了,停止测试,已经得到整数上限位数-1
archIntBits = j + 1;
break;
end
if i == i + 1 then --整数溢出了,停止测试,已经得到整数上限位数
archIntBits = j;
break;
end
end
end
_M.archIntBits = archIntBits;
local function Int2Bits(I)
local B = {};
local Sign = I < 0;
if Sign then
I = -I;
end
for i = 1, archIntBits do
B[i] = I % 2;
I = math_modf(I / 2);
end
if Sign then
for i = 1, archIntBits do
B[i] = 1 - B[i];
end
local Carry = 1;
for i = 1, archIntBits do
B[i] = B[i] + Carry;
Carry = 0;
if B[i] > 1 then
B[i] = 0;
Carry = 1;
end
end
end
return B;
end
_M.Int2Bits = Int2Bits;
local function Bits2Int(B)
local I = 0;
local Sign = B[archIntBits] == 1;
if Sign then
local Carry = 1;
for i = 1, archIntBits do
B[i] = 1 - B[i];
B[i] = B[i] + Carry;
Carry = 0;
if B[i] > 1 then
B[i] = 0;
Carry = 1;
end
end
end
for i = archIntBits, 1, -1 do
I = I * 2 + B[i];
end
if Sign then
I = -I;
end
return (math_modf(I)); --多扩一次保证返回的是整数
end
_M.Bits2Int = Bits2Int;
local band, bor, bxor, bnot, lshift, rshift;
function band(a, b)
local A = Int2Bits(a);
local B = Int2Bits(b);
local C = {};
for i = 1, archIntBits do
C[i] = A[i] * B[i];
end
return Bits2Int(C);
end
_M.band = band;
function bor(a, b)
local A = Int2Bits(a);
local B = Int2Bits(b);
local C = {};
for i = 1, archIntBits do
C[i] = A[i] + B[i];
if C[i] > 1 then
C[i] = 1;
end
end
return Bits2Int(C);
end
_M.bor = bor;
function bxor(a, b)
local A = Int2Bits(a);
local B = Int2Bits(b);
local C = {};
for i = 1, archIntBits do
C[i] = A[i] + B[i];
if C[i] > 1 then
C[i] = 0;
end
end
return Bits2Int(C);
end
_M.bxor = bxor;
function bnot(a)
local A = Int2Bits(a);
local C = {};
for i = 1, archIntBits do
C[i] = 1 - A[i];
end
return Bits2Int(C);
end
_M.bnot = bnot;
function lshift(a, b)
if b == 0 then return a; end
if b < 0 then return rshift(a, -b); end
if b >= archIntBits then return 0; end
local A = Int2Bits(a);
local C = {};
for i = 1, archIntBits do
C[i] = A[i - b] or 0;
end
return Bits2Int(C);
end
_M.lshift = lshift;
function rshift(a, b)
if b == 0 then return a; end
if (b < 0) then return lshift(a, -b); end
if (b >= archIntBits) then return 0; end
local A = Int2Bits(a);
local C = {};
for i = 1, archIntBits do
C[i] = A[i + b] or 0;
end
return Bits2Int(C);
end
_M.rshift = rshift;
return _M