如何在BitSet JAVA中左右移动位?

问题描述

我有一个具有100000位位数的位集。我想尽可能地将它左右移动。我猜BitSet类中没有移位位的功能,因此我尝试使用toLongArray()将它们转换为长数组,但按预期会产生溢出。

我发现的一个临时解决方案是将位集转换为BigInteger,然后转移BigInteger,然后将BigInteger转换回位集,但这很慢。

所以我的问题是:

  1. 是否有更好的方法来移位位集(通过移位,我指的是左右移位)
  2. 当我将位数大于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或更大,则将整个元素移动到不同位置会带来额外的麻烦。

向左移动具有一个额外的复杂性,即结果集可能比输入更大(没有更多的设置位,但是物理上更大,需要更长的数组)。