¿Hay alguna manera de crear un objeto de 128 bits en java, que se pueda manipular en bits de la misma forma que un largo o int? Quiero hacer cambios de 32 bits y quiero poder hacer un poco de operación O en toda la estructura de 128 bits.java estructura de bit 128 maninpulation
Respuesta
Aquí les presento ... una vieja idea. Ahora está muy degradado (sin potenciador de código, sin nada) a simple thingie de 128 bits que debería ser súper rápido, sin embargo. Lo que realmente quiero es una matriz basada en ByteBuffer de C alike Struct pero totalmente utilizable en java.
La idea principal es asignar más de un solo objeto a la vez y usar un puntero a la matriz. Por lo tanto, conserva mucho la memoria y la memoria se asigna en un área continua, por lo que pierde menos memoria caché (siempre es bueno).
Realicé algunas pruebas moderadas (pero el código aún no se ha probado). Permite operaciones básicas como add, xor o set/get con números de 128 bits. La regla estándar: menos documentación de la esperada aplicada desafortunadamente. Agregar código adicional para operaciones adicionales debe ser sencillo.
Aquí está el código, mira el método principal para cierto uso. ¡Aclamaciones!
package bestsss.util;
import java.util.Random;
public class Bitz {
final int[] array;
private Bitz(int n){
array=new int[n<<2];
}
public int size(){
return size(this.array);
}
private static int size(int[] array){
return array.length>>2;
}
/**
* allocates N 128bit elements. newIdx to create a pointer
* @param n
* @return
*/
public static Bitz allocate(int n){
return new Bitz(n);
}
/**
* Main utility class - points to an index in the array
* @param idx
* @return
*/
public Idx newIdx(int idx){
return new Idx(array).set(idx);
}
public static class Idx{
private static final long mask = 0xFFFFFFFFL;
//dont make the field finals
int idx;
int[] array;//keep ref. here, reduce the indirection
Idx(int[] array){
this.array=array;
}
public Idx set(int idx) {
if (Bitz.size(array)<=idx || idx<0)
throw new IndexOutOfBoundsException(String.valueOf(idx));
this.idx = idx<<2;
return this;
}
public int index(){
return idx>>2;
}
public Idx shl32(){
final int[] array=this.array;
int idx = this.idx;
array[idx]=array[++idx];
array[idx]=array[++idx];
array[idx]=array[++idx];
array[idx]=0;
return this;
}
public Idx shr32(){
final int[] array=this.array;
int idx = this.idx+3;
array[idx]=array[--idx];
array[idx]=array[--idx];
array[idx]=array[--idx];
array[idx]=0;
return this;
}
public Idx or(Idx src){
final int[] array=this.array;
int idx = this.idx;
int idx2 = src.idx;
final int[] array2=src.array;
array[idx++]|=array2[idx2++];
array[idx++]|=array2[idx2++];
array[idx++]|=array2[idx2++];
array[idx++]|=array2[idx2++];
return this;
}
public Idx xor(Idx src){
final int[] array=this.array;
int idx = this.idx;
int idx2 = src.idx;
final int[] array2=src.array;
array[idx++]^=array2[idx2++];
array[idx++]^=array2[idx2++];
array[idx++]^=array2[idx2++];
array[idx++]^=array2[idx2++];
return this;
}
public Idx add(Idx src){
final int[] array=this.array;
int idx = this.idx+3;
final int[] array2=src.array;
int idx2 = src.idx+3;
long l =0;
l += array[idx]&mask;
l += array2[idx2--]&mask;
array[idx--]=(int)(l&mask);
l>>>=32;
l += array[idx]&mask;
l += array2[idx2--]&mask;
array[idx--]=(int)(l&mask);
l>>>=32;
l += array[idx]&mask;
l += array2[idx2--]&mask;
array[idx--]=(int)(l&mask);
l>>>=32;
l += array[idx]&mask;
l += array2[idx2--];
array[idx]=(int)(l&mask);
// l>>>=32;
return this;
}
public Idx set(long high, long low){
final int[] array=this.array;
int idx = this.idx;
array[idx+0]=(int) ((high>>>32)&mask);
array[idx+1]=(int) ((high>>>0)&mask);
array[idx+2]=(int) ((low>>>32)&mask);
array[idx+3]=(int) ((low>>>0)&mask);
return this;
}
public long high(){
final int[] array=this.array;
int idx = this.idx;
long res = (array[idx]&mask)<<32 | (array[idx+1]&mask);
return res;
}
public long low(){
final int[] array=this.array;
int idx = this.idx;
long res = (array[idx+2]&mask)<<32 | (array[idx+3]&mask);
return res;
}
//ineffective but well
public String toString(){
return String.format("%016x-%016x", high(), low());
}
}
public static void main(String[] args) {
Bitz bitz = Bitz.allocate(256);
Bitz.Idx idx = bitz.newIdx(0);
Bitz.Idx idx2 = bitz.newIdx(2);
System.out.println(idx.set(0, 0xf));
System.out.println(idx2.set(0, Long.MIN_VALUE).xor(idx));
System.out.println(idx.set(0, Long.MAX_VALUE).add(idx2.set(0, 1)));
System.out.println("==");
System.out.println(idx.add(idx));//can add itself
System.out.println(idx.shl32());//left
System.out.println(idx.shr32());//and right
System.out.println(idx.shl32());//back left
//w/ alloc
System.out.println(idx.add(bitz.newIdx(4).set(0, Long.MAX_VALUE)));
//self xor
System.out.println(idx.xor(idx));
//random xor
System.out.println("===init random===");
Random r = new Random(1112);
for (int i=0, s=bitz.size(); i<s; i++){
idx.set(i).set(r.nextLong(), r.nextLong());
System.out.println(idx);
}
Idx theXor = bitz.newIdx(0);
for (int i=1, s=bitz.size(); i<s; i++){
theXor.xor(idx.set(i));
}
System.out.println("===XOR===");
System.out.println(theXor);
}
}
Nº
En este momento no hay una respuesta mejor.
Un enfoque puede ser crear un objeto envoltorio para dos valores largos e implementar la funcionalidad requerida teniendo en cuenta la firma de los operadores relevantes. También hay BigInteger [actualizado desde la respuesta de rlibby], pero no proporciona el soporte requerido.
Happy coding.
No hay ningún tipo de datos más largo que long
(I han registrado esto como una RFE junto con un punto flotante de 128 bits;)
Puede crear un objeto con cuatro int
valores de 32 bits y apoyar estas operaciones bastante fácilmente.
No puede definir ningún tipo nuevo al que pueda aplicar los operadores bit a bit integrados de Java.
Sin embargo, ¿podría simplemente usar java.math.BigInteger
? BigInteger define todas las operaciones de bits definidas para tipos integrales (como métodos). Esto incluye, por ejemplo, BigInteger.or(BigInteger)
.
Quizás BitSet
te sea útil.
Tiene las operaciones lógicas, y me imagino que el cambio no sería tan difícil de implementar dado sus métodos de utilidad.
En realidad, la implementación del cambio * eficientemente * usando la API 'BitSet' sería complicado. –
@Stephen Eso es verdad. – corsiKa
@Stephen: por extraño que parezca, el cambio a la derecha ya está implementado, vea 'BitSet.get (int, int)'. por alguna razón, sin embargo, descuidaron el turno de la izquierda. – jtahlborn
tres posibilidades se han identificado:
La clase
BitSet
ofrece algunas de las operaciones que necesita, pero ningún método "cambio". Para poner en práctica este método faltante, que había necesidad de hacer algo como esto:BitSet bits = new BitSet(128); ... // shift left by 32bits for (int i = 0; i < 96; i++) { bits.set(i, bits.get(i + 32)); } bits.set(96, 127, false);
La clase
BigInteger
proporciona todos los métodos (más o menos), pero desdeBigInteger
es inmutable, que podría resultado en una tasa de creación de objeto excesiva ... dependiendo de cómo use los conjuntos de bits. (También existe el problema de queshiftLeft(32)
no va a cortar los bits de la izquierda ... pero se puede hacer frente a esto mediante el usoand
para enmascarar los bits en el índice 128 y superior.)si el rendimiento es la clave preocupación, la implementación de una clase personalizada con 4
int
o 2long
probablemente dará mejor rendimiento. (Que en realidad es la opción más rápida de las dos dependerá de la plataforma de hardware, la JVM, etc. Probablemente elegiría la versiónlong
porque sería más simple codificar ... y solo trataría de optimizar aún más si los perfiles indicaban que fue una actividad potencialmente valiosa).Además, puede diseñar las API para que se comporten exactamente como lo requiera (módulo de las restricciones del lenguaje Java). La desventaja es que tienes que implementar y probar todo, y estarás cableando el número mágico 128 en tu código base.
siempre es mejor incluso en 32 bits (el registro mmx se puede usar para realizar una sola carga) – bestsss
@bestsss asume una arquitectura x86/x86-64. –
@Stephan, x86, x64 tiene sus 64 registros nativos, pero incluso los procesadores 'pequeños' XScale, ARMv7 tienen registros de 64 bits para manejar la carga en una sola instrucción.Ciertamente, "siempre" se utiliza con demasiada frecuencia, ya que no todas las CPU tendrían instrucciones útiles de carga de 64 bits. – bestsss
Afaik, la JVM simplemente convertirá todo lo que codifique en trozos de 32 bits haga lo que haga. JVM es de 32 bits. Creo que incluso la versión de 64 bits de JVM procesa en gran medida en fragmentos de 32 bits. Sin duda, debería conservar la memoria ... Simplemente vas a ralentizar tu código a medida que el JIT intenta optimizar el desastre que creas. En C/C++, etc. no tiene sentido hacer esto tampoco, ya que aún tendrás la impedancia del hecho de que son registros de 32 o 64 bits en el hardware que probablemente uses. Incluso Intel Xenon Phi (tiene registros vectoriales de 512bit) es solo un conjunto de elementos de 32 y 64 bits.
Si desea implementar algo así, puede intentar hacerlo en GLSL u OpenCL si tiene hardware de GPU disponible. En 2015, Java Sumatra se lanzará como parte de Java 9, al menos ese es el plan. Luego, tendrá la capacidad de integrar java con el código GPU de fábrica. Eso ES un gran problema, ¡de ahí el nombre ilustre!
- 1. ARM NEON: comparando valores de 128 bit
- 2. Java Crit-bit Trees
- 3. Encriptación de datos de 128 bits con Java
- 4. Java performance 64 bit
- 5. Reemplazar bit menos significativo con operaciones bit a bit
- 6. AND bit a bit, bit a bit pregunta Incluido O, en Java
- 7. ¿Puedo usar OR bit a bit para enumeraciones de Java
- 8. Comparación bit a bit Java de un byte
- 9. Convirtiendo Endianess en una estructura de campo de bit
- 10. Almacenando dos registros x86 de 32 bits en el registro de 128 bit xmm
- 11. j8583 no puede manejar el campo 128
- 12. Java 64 bit Pregunta JDK
- 13. Java - desplazamiento circular usando operaciones bit a bit
- 14. Operaciones bit a bit con enteros grandes
- 15. x86 operaciones atómicas de 128 bits
- 16. ¿Estructura en disco para almacenar un conjunto grande de enteros de 128 bits?
- 17. Colecciones Java (estructura LIFO)
- 18. Java pregunta estructura de datos
- 19. Estructura de columnas múltiples Java
- 20. Implementación de ArrayDeque.allocateElements (operaciones bit a bit)
- 21. Mejor estructura de la estructura del proyecto web de Java
- 22. Tamaños de estructuras en 32 bit y 64 bit
- 23. ¿Por qué el rango de bytes -128 a 127 en Java?
- 24. contador SSE de 128 bits
- 25. Python: aritmética bit a bit sin signo de 32 bit
- 26. Operaciones bit a bit en el corto
- 27. Java: ¿gran estructura hash persistente?
- 28. ¿Qué hace una O exclusiva de bit a bit en Java?
- 29. Efecto de un operador bit a bit en un booleano en Java
- 30. Estructura de directorio de interfaces Java?
este fue el enfoque que también estaba considerando – richs