问题描述
我有一个具有100000位位数的位集。我想尽可能地将它左右移动。我猜BitSet类中没有移位位的功能,因此我尝试使用toLongArray()
将它们转换为长数组,但按预期会产生溢出。
我发现的一个临时解决方案是将位集转换为BigInteger,然后转移BigInteger,然后将BigInteger转换回位集,但这很慢。
所以我的问题是:
- 是否有更好的方法来移位位集(通过移位,我指的是左右移位)
- 当我将位数大于64的位集转换为长数组时,在数组中得到负数。当BitSet仅代表1个数字的位时,为什么首先要有一个函数
toLongArray()
。如果我错了,请纠正我。
以下是使用BigInteger的代码。
public static BitSet toBitSet(BigInteger val) {
if(val.signum() < 0)
throw new IllegalArgumentException("Negative value: " + val);
return BitSet.valueOf(reverse(val.toByteArray()));
}
static byte[] reverse(byte[] bytes) {
for(int i = 0; i < bytes.length/2; i++) {
byte temp = bytes[i];
bytes[i] = bytes[bytes.length-i-1];
bytes[bytes.length-i-1] = temp;
}
return bytes;
}
public static BigInteger toBigInteger(BitSet val) {
return new BigInteger(1,reverse(val.toByteArray()));
}
public static BitSet shiftLeft(BitSet bits,int n) {
BigInteger temp= toBigInteger(bits);
temp= temp.shiftLeft(n);
return toBitSet(temp);
}
PS:我找到的所有答案都是针对位数
解决方法
当我将位数大于64的位集转换为长数组时,在数组中得到负数。
负元素非常好,这只是使用 // MysticLight_SDK.h : header file
//
#pragma once
typedef int (*LPMLAPI_Initialize)();
typedef int (*LPMLAPI_GetDeviceInfo)(SAFEARRAY** pDevType,SAFEARRAY** pLedCount);
typedef int (*LPMLAPI_GetDeviceName)(BSTR type,SAFEARRAY** pDevName);
typedef int (*LPMLAPI_GetDeviceNameEx)(BSTR type,DWORD index,BSTR* pDevName);
typedef int (*LPMLAPI_GetErrorMessage)(int ErrorCode,BSTR* pDesc);
typedef int (*LPMLAPI_GetLedName)(BSTR type,SAFEARRAY** pLedName);
typedef int (*LPMLAPI_GetLedInfo)(BSTR type,BSTR* pName,SAFEARRAY** pLedStyles);
typedef int (*LPMLAPI_GetLedColor)(BSTR type,DWORD* R,DWORD* G,DWORD* B);
typedef int (*LPMLAPI_GetLedStyle)(BSTR type,BSTR* style);
typedef int (*LPMLAPI_GetLedMaxBright)(BSTR type,DWORD* maxLevel);
typedef int (*LPMLAPI_GetLedBright)(BSTR type,DWORD* currentLevel);
typedef int (*LPMLAPI_GetLedMaxSpeed)(BSTR type,DWORD* maxLevel);
typedef int (*LPMLAPI_GetLedSpeed)(BSTR type,DWORD* currentLevel);
typedef int (*LPMLAPI_SetLedColor)(BSTR type,DWORD R,DWORD G,DWORD B);
typedef int (*LPMLAPI_SetLedColors)(BSTR type,DWORD AreaIndex,SAFEARRAY** pLedName,DWORD* B);
typedef int (*LPMLAPI_SetLedColorEx)(BSTR type,BSTR pLedName,DWORD B,DWORD );
typedef int (*LPMLAPI_SetLedColorSync)(BSTR type,DWORD );
typedef int (*LPMLAPI_SetLedStyle)(BSTR type,BSTR style);
typedef int (*LPMLAPI_SetLedBright)(BSTR type,DWORD level);
typedef int (*LPMLAPI_SetLedSpeed)(BSTR type,DWORD level);
的所有64位的结果,从而包括了符号位。只要您期望它就没关系。基本上,仅当使用带符号的解释进行打印时,它看起来才是奇怪的,否则不是一件坏事。
所以我尝试使用
Traceback (most recent call last): File ".\check.py",line 5,in <module> cppyy.include('MysticLight_SDK.h') File "C:\Users\sarfaraz\AppData\Local\Programs\Python\Python37\lib\site-packages\cppyy\__init__.py",line 217,in include raise ImportError('Failed to load header file "%s"%s' % (header,err.err)) ImportError: Failed to load header file "MysticLight_SDK.h" In file included from input_line_18:1: ./MysticLight_SDK.h:7:38: error: unknown type name 'SAFEARRAY' typedef int (*LPMLAPI_GetDeviceInfo)(SAFEARRAY** pDevType,SAFEARRAY** pLedCount); ^ ./MysticLight_SDK.h:7:60: error: unknown type name 'SAFEARRAY' typedef int (*LPMLAPI_GetDeviceInfo)(SAFEARRAY** pDevType,SAFEARRAY** pLedCount); ^ ./MysticLight_SDK.h:8:38: error: unknown type name 'BSTR' typedef int (*LPMLAPI_GetDeviceName)(BSTR type,SAFEARRAY** pDevName); ^ ./MysticLight_SDK.h:8:49: error: unknown type name 'SAFEARRAY' typedef int (*LPMLAPI_GetDeviceName)(BSTR type,SAFEARRAY** pDevName); ^ ./MysticLight_SDK.h:9:40: error: unknown type name 'BSTR' typedef int (*LPMLAPI_GetDeviceNameEx)(BSTR type,BSTR* pDevName); ^ ./MysticLight_SDK.h:9:64: error: unknown type name 'BSTR' typedef int (*LPMLAPI_GetDeviceNameEx)(BSTR type,BSTR* pDevName); ^ ./MysticLight_SDK.h:10:55: error: unknown type name 'BSTR' typedef int (*LPMLAPI_GetErrorMessage)(int ErrorCode,BSTR* pDesc); ^ ./MysticLight_SDK.h:11:35: error: unknown type name 'BSTR' typedef int (*LPMLAPI_GetLedName)(BSTR type,SAFEARRAY** pLedName); ^ ./MysticLight_SDK.h:11:46: error: unknown type name 'SAFEARRAY' typedef int (*LPMLAPI_GetLedName)(BSTR type,SAFEARRAY** pLedName); ^ ./MysticLight_SDK.h:12:35: error: unknown type name 'BSTR' typedef int (*LPMLAPI_GetLedInfo)(BSTR type,SAFEARRAY** pLedStyles); ^ ./MysticLight_SDK.h:12:59: error: unknown type name 'BSTR' typedef int (*LPMLAPI_GetLedInfo)(BSTR type,SAFEARRAY** pLedStyles); ^ ./MysticLight_SDK.h:12:72: error: unknown type name 'SAFEARRAY' typedef int (*LPMLAPI_GetLedInfo)(BSTR type,SAFEARRAY** pLedStyles); ^ ./MysticLight_SDK.h:13:36: error: unknown type name 'BSTR' typedef int (*LPMLAPI_GetLedColor)(BSTR type,DWORD* B); ^ ./MysticLight_SDK.h:14:36: error: unknown type name 'BSTR' typedef int (*LPMLAPI_GetLedStyle)(BSTR type,BSTR* style); ^ ./MysticLight_SDK.h:14:60: error: unknown type name 'BSTR' typedef int (*LPMLAPI_GetLedStyle)(BSTR type,BSTR* style); ^ ./MysticLight_SDK.h:15:40: error: unknown type name 'BSTR' typedef int (*LPMLAPI_GetLedMaxBright)(BSTR type,DWORD* maxLevel); ^ ./MysticLight_SDK.h:16:37: error: unknown type name 'BSTR' typedef int (*LPMLAPI_GetLedBright)(BSTR type,DWORD* currentLevel); ^ ./MysticLight_SDK.h:17:39: error: unknown type name 'BSTR' typedef int (*LPMLAPI_GetLedMaxSpeed)(BSTR type,DWORD* maxLevel); ^ ./MysticLight_SDK.h:18:36: error: unknown type name 'BSTR' typedef int (*LPMLAPI_GetLedSpeed)(BSTR type,DWORD* currentLevel); ^ fatal error: too many errors emitted,stopping now [-ferror-limit=]
将它们转换为长数组,但按预期会产生溢出。
尽管这是一个合理的实施策略,所以让我们对其进行修复。我想您是在不处理“进位”的情况下单独移动了每个元素。左移需要发生的是,将元素的高位放入下一个元素的低位。右移则相反。例如,对于import cppyy
cppyy.include('MysticLight_SDK.h')
cppyy.cppdef("""
int main() {
int c;
int a = 10;
int b = 10;
c = a+b;
return c;
};""")
c = cppyy.gbl.main
print(c())
(最多63)(未测试)
long
如果toLongArray()
可以为64或更大,则将整个元素移动到不同位置会带来额外的麻烦。
向左移动具有一个额外的复杂性,即结果集可能比输入更大(没有更多的设置位,但是物理上更大,需要更长的数组)。