2010-12-15 11 views
13

Estoy tratando de implementar un protocolo de red existente que hace un uso intensivo de los tipos de datos Unsigned, que no son compatibles con Java. Lo que hago actualmente es para cada tipo de datos, elija el siguiente más grande para que el número sin firmar pueda caber en la región positiva y luego use el desplazamiento de bytes para obtener el efecto deseado. Dado que esto es bastante propenso a errores y para un unsigned en adelante tengo que usar BigInteger, que es mucho más pesado que los tipos expandidos, me preguntaba si no hay una mejor manera de lograr esto.Unsigned Int en Java

Respuesta

16

Dependiendo de lo que esté haciendo, puede simplemente tratar como un valor de 64 bits y int como un valor de 32 bits. La mayoría de las operaciones, especialmente readInt/Long writeInt/Long funcionan igual al ignorar el signo.

Puede dar un ejemplo de la operación que realiza en estos números y quizás podamos sugerir cómo haría lo mismo sin tener que expandir el tipo.

Por ejemplo, ++, -, +, -, *, ==,! =, < < funcionan todos igual independientemente de signess (es decir, dan la misma respuesta). para >> puede sustituir >>>

Son las funciones /,%,>,> =, <, < = y las funciones de impresión que asumen valores con signo, pero debería poder solucionarlos (si utiliza estas).

p. Ej.

long unsignedA = 
long unsignedB = 
boolean greater = unsignedA + Long.MIN_VALUE > unsignedB + Long.MIN_VALUE 

EDITAR: ¿Por qué funciona esto? En parte porque java no tiene excepciones de desbordamiento/subdesbordamiento.

p. Ej.

byte unsignedA = 0; 
unsignedA--; 
// unsignedA == FF, is this -1 or 255? Java assumes the former but you assume the later 

byte unsignedB = unsignedA * unsignedA; 
// unsignedB is -1 * -1 = 1 or (byte) (255*255) = (byte) 65525 = 1. 
+0

Hm, eso suena prometedor, esperaba simplemente crear un InputStream y de ahí simplemente trabajar con los valores como se esperaba, en lugar de arrastrarlos por el programa. El problema es que en su mayor parte representan direcciones IP, números de versión (muy pesados,><, <= and > =), cryptohashes (no hay problema allí, probablemente) y marcas de tiempo (una vez más pesadas en las comparaciones). – cdecker

+0

Para las direcciones IP, tendrá que utilizar el truco de engaño o ampliar a largo. para las marcas de tiempo largas, debe poder asumir que están entre 0 y Long.MAX_VALUE si están en milisegundos. ¿Sus números de versión usan la parte superior? ¿Puedes dar un ejemplo de uno que lo haga? (si es así, también debe sesgar la comparación) –

+0

Las marcas de tiempo milli-second largas y firmadas están limitadas al año 292,471,208 si comienza en 1 BC (no hubo año 0), –

Cuestiones relacionadas