将图像哈希中使用的 C# BitCount 方法转换为涉及位运算符的 T-SQL
Convert C# BitCount method used in image hashing to T-SQL involving Bitwise operators
我正在尝试将以下 BitCount
方法转换为 T-SQL
,但我什至不知道如何开始。
例如,如何手动实例化一个 varbinary
变量,类似于下面的 bitCounts
数组。顺便说一句,原始代码位于 on github。将此方法转换为 T-SQL
的任何帮助都将非常有帮助。
几个输入,这个函数对应的输出是:
- 输入=34762711265992831;输出=23
- 输入=1130323790528512;输出=6
- 输入=33900573146222676;输出=17
- 输入=31648412230258808;输出=18
- 输入=31877043259982883;输出=11
- 输入=0;输出=0
private static byte[] bitCounts = {
0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
};
/// <summary>
/// Utility function for similarity.
/// </summary>
/// <param name="num">The hash we are counting.</param>
/// <returns>The total bit count.</returns>
private static uint BitCount(ulong num)
{
uint count = 0;
for (; num > 0; num >>= 8)
count += bitCounts[(num & 0xff)];
return count;
}
我在这里找到了答案http://www.dbforums.com/showthread.php?1630934-bit-counting
CREATE FUNCTION dbo.bit_count (@num AS BIGINT)RETURNS INT AS
BEGIN
DECLARE @msb INT
SET @msb = 0
IF @num < 0
BEGIN -- BIGINT is signed so treat the MSB differently
SET @msb = 1
SET @num = 0x7FFFFFFFFFFFFFFF & @num
END
SET @num = @num - ((@num / 2) & 0x5555555555555555)
SET @num = (@num & 0x3333333333333333) + ((@num / 4) & 0x3333333333333333)
SET @num = (@num + @num / 0x10) & 0x0F0F0F0F0F0F0F0F
SET @num = @num + @num / 0x100
SET @num = @num + @num / 0x10000
SET @num = @num + @num / 0x100000000
RETURN (@num & 0x3F) + @msb
END
我正在尝试将以下 BitCount
方法转换为 T-SQL
,但我什至不知道如何开始。
例如,如何手动实例化一个 varbinary
变量,类似于下面的 bitCounts
数组。顺便说一句,原始代码位于 on github。将此方法转换为 T-SQL
的任何帮助都将非常有帮助。
几个输入,这个函数对应的输出是:
- 输入=34762711265992831;输出=23
- 输入=1130323790528512;输出=6
- 输入=33900573146222676;输出=17
- 输入=31648412230258808;输出=18
- 输入=31877043259982883;输出=11
- 输入=0;输出=0
private static byte[] bitCounts = {
0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
};
/// <summary>
/// Utility function for similarity.
/// </summary>
/// <param name="num">The hash we are counting.</param>
/// <returns>The total bit count.</returns>
private static uint BitCount(ulong num)
{
uint count = 0;
for (; num > 0; num >>= 8)
count += bitCounts[(num & 0xff)];
return count;
}
我在这里找到了答案http://www.dbforums.com/showthread.php?1630934-bit-counting
CREATE FUNCTION dbo.bit_count (@num AS BIGINT)RETURNS INT AS
BEGIN
DECLARE @msb INT
SET @msb = 0
IF @num < 0
BEGIN -- BIGINT is signed so treat the MSB differently
SET @msb = 1
SET @num = 0x7FFFFFFFFFFFFFFF & @num
END
SET @num = @num - ((@num / 2) & 0x5555555555555555)
SET @num = (@num & 0x3333333333333333) + ((@num / 4) & 0x3333333333333333)
SET @num = (@num + @num / 0x10) & 0x0F0F0F0F0F0F0F0F
SET @num = @num + @num / 0x100
SET @num = @num + @num / 0x10000
SET @num = @num + @num / 0x100000000
RETURN (@num & 0x3F) + @msb
END