Existe uma maneira de declarar um int não assinado em Java?
Ou a pergunta também pode ser enquadrada da seguinte maneira: Qual é o equivalente em Java de não assinado?
Só para dizer o contexto que eu estava observando na implementação do Java String.hashcode()
. Eu queria testar a possibilidade de colisão se o número inteiro fosse 32 int sem sinal.
>>>
operador em vez de>>
.Respostas:
Java não possui um tipo de dados para números inteiros não assinados .
Você pode definir um em
long
vez de umint
se precisar armazenar valores grandes.Você também pode usar um número inteiro assinado como se não estivesse assinado. O benefício da representação de complemento de dois é que a maioria das operações (como adição, subtração, multiplicação e deslocamento à esquerda) são idênticas em nível binário para números inteiros assinados e não assinados. Algumas operações (divisão, mudança à direita, comparação e elenco), no entanto, são diferentes. No Java SE 8, novos métodos na
Integer
classe permitem usar totalmente oint
tipo de dados para executar aritmética não assinada :Observe que as
int
variáveis ainda são assinadas quando declaradas, mas a aritmética não assinada agora é possível usando esses métodos naInteger
classe.fonte
int
tipo de dados para representar um número inteiro de 32 bits não assinado, que possui um valor mínimo de0
e um valor máximo de2^32-1
. - consulte docs.oracle.com/javase/tutorial/java/nutsandbolts/… e docs.oracle.com/javase/8/docs/api/java/lang/Integer.htmlint
como se não fosse assinado usando vários métodos.Há uma API para Inteiro e Longo sem sinal no Java 8!
fonte
Integer
classe em Java 8 permite a utilização de unsigned int, é a diferença entre apenas espaço e velocidade (já que em C / C ++ são primitivas, enquanto em Java é um invólucro de objeto inteiro)int
rolam, mesmo que estejam assinados. É em C / C ++ que o rolo não assinado passa, mas o sinal causa "Comportamento indefinido" no estouro. Se "rolar" é sua única preocupação, você não precisa de assinatura. Eu acho que é por isso que as rotinas CRC etc. funcionam em Java sem esforços extras. E é por isso que a nova API adiciona apenas análise, formatação, comparações, divisão e restante. Todas as outras operações, nomeadamente todas as manipulações de bits, mas também adição, subtração, multiplicação, etc., estão fazendo a coisa certa de qualquer maneira.Se um valor em um int é assinado ou não assinado depende de como os bits são interpretados - Java interpreta os bits como um valor assinado (ele não possui primitivas não assinadas).
Se você tem um int que deseja interpretar como um valor não assinado (por exemplo, você lê um int de um DataInputStream que você sabe que contém um valor não assinado), pode executar o seguinte truque.
Observe que é importante que o literal hexadecimal seja um literal longo, não um literal int - daí o 'l' no final.
fonte
0xFFFFFF
e manter o int?Precisávamos números não assinados para modelar do MySQL não assinado
TINYINT
,SMALLINT
,INT
,BIGINT
em jOOQ , que é por isso que criamos jOOU , uma oferta biblioteca minimalista invólucro tipos para números inteiros não assinados em Java. Exemplo:Todos esses tipos se estendem
java.lang.Number
e podem ser convertidos em tipos primitivos e de ordem superiorBigInteger
. Espero que isto ajude.(Aviso: trabalho para a empresa por trás dessas bibliotecas)
fonte
Para números não assinados, você pode usar estas classes da biblioteca Guava :
Eles suportam várias operações:
O que parece estar faltando no momento são os operadores de troca de bytes. Se você precisar, pode usar o BigInteger a partir de Java.
fonte
Use
char
para números inteiros não assinados de 16 bits.fonte
Talvez seja isso que você quis dizer?
getUnsigned(0)
→ 0getUnsigned(1)
→ 1getUnsigned(Integer.MAX_VALUE)
→ 2147483647getUnsigned(Integer.MIN_VALUE)
→ 2147483648getUnsigned(Integer.MIN_VALUE + 1)
→ 2147483649fonte
2 * (long) Integer.MAX_VALUE + 2
é mais fácil entender do que0x1_0000_0000L
? A esse respeito, por que não simplesmentereturn signed & 0xFFFF_FFFFL;
?Parece que você pode lidar com o problema de assinatura executando um "AND lógico" nos valores antes de usá-los:
Exemplo (o valor de
byte[]
header[0]
é0x86
):Resultado:
fonte
Há boas respostas aqui, mas não vejo nenhuma demonstração de operações bit a bit. Como Visser (a resposta atualmente aceita) diz, o Java assina números inteiros por padrão (o Java 8 tem números inteiros não assinados, mas eu nunca os usei). Sem mais delongas, vamos fazê-lo ...
Exemplo RFC 868
O que acontece se você precisar gravar um número inteiro não assinado no IO? Um exemplo prático é quando você deseja exibir o tempo de acordo com a RFC 868 . Isso requer um número inteiro não assinado de 32 bits, big endian, que codifica o número de segundos desde 00:00 de 1º de janeiro de 1900. Como você codificaria isso?
Crie seu próprio número inteiro de 32 bits não assinado como este:
Declarar uma matriz de bytes de 4 bytes (32 bits)
Isso inicializa a matriz, consulte As matrizes de bytes são inicializadas como zero em Java? . Agora você precisa preencher cada byte na matriz com informações na ordem big-endian (ou little-endian se você quiser causar estragos). Supondo que você tenha um longo contendo o tempo (inteiros longos têm 64 bits em Java) chamado
secondsSince1900
(que utiliza apenas os primeiros 32 bits, e você já lidou com o fato de que Date faz referência a 00:00 em 1º de janeiro de 1970), você pode usar o AND lógico para extrair bits dele e mudar esses bits para posições (dígitos) que não serão ignorados quando colocados em um byte e na ordem big endian.my32BitUnsignedInteger
Agora, nosso é equivalente a um número inteiro big endian não assinado de 32 bits que adere ao padrão RCF 868. Sim, o tipo de dados longo é assinado, mas ignoramos esse fato, porque assumimos que os segundosSince1900 usavam apenas os 32 bits inferiores). Por envolver o comprimento em um byte, todos os bits maiores que 2 ^ 7 (dois primeiros dígitos em hexadecimal) serão ignorados.Fonte referenciada: Java Network Programming, 4ª Edição.
fonte
Acabei de criar esse pedaço de código, que converte "this.altura" de número negativo em positivo. Espero que isso ajude alguém em necessidade
fonte
Você pode usar a função Math.abs (number). Retorna um número positivo.
fonte
MIN_VALUE
0