2009-12-03 13 views
42

Come posso dichiarare un valore unsigned short in Java?non firmato corto in java

+2

questione connessa, se siete interessati alla motivazione alla base di questo: "Perché il sostegno non Java unsigned int?" Http: // StackOverflow .com/questions/430346 – Heinzi

+4

@ PP: Se vuoi un linguaggio con i punti di forza di Java e C++, posso consigliare Scala. E 'davvero bravo a farti scatenare con i tipi. –

+2

usa un corto firmato. tutte le operazioni bit appropriate hanno variazioni che trattano il valore come non firmato. – james

risposta

59

Non si può, davvero. Java non ha alcun tipo di dati senza segno, ad eccezione di char.

Certo si potrebbe usa char - è un tipo senza segno a 16 bit - ma che sarebbe orribile a mio avviso, come char è chiaramente destinata ad essere per il testo: quando il codice utilizza char, mi aspetto che sia usando per le unità di codice UTF-16 che rappresentano il testo che è interessante per il programma, non per gli interi arbitrari a 16 bit senza segno con nessuna relazione con il testo.

+17

@Jon: Sembra non esserci alcun modo in Java di avere un normale byte a livello di macchina, ovvero una posizione a 8 bit che può contenere valori [0-255] invece di [-128 - +127]. Non posso credere che ci facciano usare ** byte firmati **, quando tutto ciò che devi fare in C è pronunciare "unsigned char". Una volta che inizi a percorrere solo i tipi di dati firmati, questo rovina tutte le tue bitmap non firmate. Davvero abbastanza sgradevole. I progettisti Java pensavano di semplificare le cose per renderle meno soggette a errori, ma ancora una volta tutto ciò che riuscivano a fare era renderle molto più difficili e più soggette a errori di prima. C'è molto di questo in Java. – tchrist

+2

@Jon: OTOH, dal momento che '' char' di Java non è utilizzabile per i codepoint Unicode, puoi anche usarlo per i corti senza segno: non sarà più orribile di qualsiasi codice esistente usando 'char' quando dovrebbero davvero usare' int'. – ninjalj

+4

@ninjalj, Oh * dove * sei 'typedef'? – Pacerier

-1

Java non ha tipi senza segno. A cosa ti serve?

Java ha tuttavia il tipo di dati 'byte'.

+0

byte è 8 bit, corto è 16 bit ... non credo che il byte funzionerà :-) – TofuBeer

+0

vorrei costruire un array multidimensionale con ad esempio 10000 * 10000 voci di numeri brevi ... ecco perché io pensato a cortometraggi senza segno, per allocare meno memoria – maiky

+0

Grazie per la correzione, TofuBeer. Troppo veloce nel sorteggio, immagino. – CBFraser

1

Sì, non è possibile se si desidera utilizzare il valore in operazioni di codice e bit.

9

È possibile utilizzare un carattere, poiché è un valore a 16 bit senza segno (sebbene tecnicamente si tratti di un carattere unicode, quindi in futuro potrebbe cambiare in modo da essere un valore a 24 bit) ... l'altra alternativa è utilizzare un int e assicurarsi che sia nel raggio d'azione.

Non usare un char - utilizzare un int :-)

Ed ecco un link discussing Java and the lack of unsigned.

+3

char è definito per essere 16 bit, non un carattere Unicode (qualunque cosa significhi), sempre e per sempre. Se il char fosse cambiato a 24 bit, non sarebbe più Java. – Ken

+1

Non credo che cambierà mai neanche. Il motivo per cui 16 bit supporta l'unicode (dal JLS: "La piattaforma Java tiene traccia delle specifiche Unicode man mano che evolve." E "Lo standard Unicode era originariamente progettato come una codifica di caratteri a 16 bit a larghezza fissa") e da java .lang.Character: "I metodi che accettano solo un valore char non possono supportare caratteri supplementari" - così il char originale era 16 bit perché quello era l'ampio unicode. Ora Unicode è più grande e char non può più rappresentare tutti i caratteri Unicode. – TofuBeer

-1

È possibile programmare una classe ShortUnsigned e definire i metodi per gli operatori desiderati. Non sarà possibile sovraccaricare + e - e gli altri su di essi, né avere la conversione di tipo implicita con altri tipi di oggetti primitivi o numerici, purtroppo.

Come alcuni degli altri risponditori, mi chiedo perché questa urgente necessità di cortocircuito senza segno che nessun altro tipo di dati riempirà.

12

Se davvero bisogno di un valore con esattamente 16 bit:

Soluzione 1: Utilizzare la disposizione firmato breve e smettere di preoccuparsi per il segno, a meno che non si deve fare il confronto (<, < =,>, > =) o operazioni di divisione (/,%, >>). Vedi this answer per come gestire i numeri firmati come se fossero non firmati.

Soluzione 2 (dove soluzione 1 non si applica): Utilizzare i 16 bit inferiori int e rimuovere i bit superiori con & 0xffff ove necessario.

+0

'sBuff.append (new Integer (iArray [i ++] & 0xffff) +", ");' Grazie! – essa

9

Questo è un thread davvero stantio, ma a beneficio di chiunque venga dopo. Il carattere è un tipo numerico. Supporta tutti gli operatori matematici, operazioni bit, ecc. Si tratta di un unsigned 16.

Elaboriamo i segnali registrati dall'hardware incorporato personalizzato in modo da gestire un sacco di 16 senza segno dagli A-D. Abbiamo usato chars dappertutto per anni e non abbiamo mai avuto problemi.

-1

programma semplice per mostrare il motivo per cui sono necessari i numeri senza segno:

package shifttest; 
public class ShiftTest{ 
    public static void main(String[] args){ 
     short test = -15000; 
     System.out.format ("0x%04X 0x%04X 0x%04X 0x%04X 0x%04X\n", 
      test, test>>1, test>>2, test>>3, test>>4); 
    } 
} 

risultati:

0xC568 0xFFFFE2B4 0xFFFFF15A 0xFFFFF8AD 0xFFFFFC56 

Ora, per quelli che non sono tipi di sistema:

Java non uno spostamento aritmetico perché il L'operando è firmato, tuttavia, ci sono casi in cui un cambiamento logico sarebbe appropriato ma JAVA (Sun in particolare), lo riteneva inutile, peccato per noi per la loro miopia. Maiusc, And, Or e Exclusive O sono strumenti limitati quando tutti i numeri sono stati firmati. Questo è un problema particolare quando si interfaccia con dispositivi hardware che comunicano bit di computer "REALI" di 16 bit o più. "char" non è garantito per funzionare (è largo due byte ora), ma in diverse lingue basate su gif orientale come il cinese, il coreano e il giapponese, richiedono almeno 3 byte. Non conosco il numero necessario per i linguaggi di stile degli sandscript. Il numero di byte non dipende dal programmatore piuttosto dal comitato standard per JAVA. Quindi basare il char come 16 bit ha un rischio a valle. Per implementare in sicurezza pantaloncini senza firma JAVA, la classe speciale è la soluzione migliore basata sulle ambiguità di cui sopra. Lo svantaggio della classe è l'incapacità di sovraccaricare le operazioni matematiche per questa classe speciale. Molti dei contributori per questo thread hanno evidenziato con precisione questi problemi, ma il mio contributo è un esempio di codice funzionante e la mia esperienza con linguaggi di 3 gif in C++ sotto Linux.

+0

È possibile utilizzare, 'System.out.formato ("0x% 04X 0x% 04X 0x% 04X 0x% 04X 0x% 04X \ n", test, test e 0xffff >> 1, test e 0xffff >> 2, test e 0xffff >> 3, test e 0xffff >> 4); '. Questo ti darà uno spostamento senza firma di corto. Tuttavia questo aggiunge 1 operazione (bit a bit &) a ogni merda. – CITBL

+0

Java ha un operatore logico di spostamento a destra, '>>>'. Inoltre, 'char' non cambierà mai le sue dimensioni. –

0

Ha detto che voleva creare un cortometraggio multidimensionale. Eppure nessuno ha suggerito operatori bit a bit? Da quello che ho letto, vuoi usare interi a 16 bit su interi a 32 bit per risparmiare memoria?

Quindi, in primo luogo, per iniziare 10.000 x 10.000 valori brevi è 1.600.000.000 bit, 200.000.000 byte, 200.000 kilobyte, 200 megabyte.

Se hai bisogno di qualcosa con 200 MB di memoria, potresti voler riprogettare questa idea. Anch'io non credo che si possa anche compilare e tanto meno correre. Non si dovrebbe mai inizializzare array di grandi dimensioni come questo se si utilizzano due funzionalità chiamate Caricamento su richiesta e Cache dati. In pratica il caricamento su richiesta si riferisce all'idea di caricare i dati solo quando necessario. Quindi il caching dei dati fa la stessa cosa, ma utilizza un lavoro di frame personalizzato per eliminare la vecchia memoria e aggiungere nuove informazioni, se necessario. Questo è difficile da ottenere buone prestazioni di velocità. Ci sono altre cose che puoi fare, ma quelle due sono le mie preferite se fatte bene.

Torna a quello che stavo dicendo di operatori bit a bit.

Quindi un intero a 32 bit o in "int" Java. È possibile memorizzare quelli che vengono chiamati "bit", quindi supponiamo che tu abbia 32 valori booleani che in Java tutti i valori occupano 32 bit (eccetto lungo) o per gli array che occupano 8 per byte, 16 per breve e 32 per int . Quindi, a meno che non si disponga di array, non si ottengono vantaggi di memoria dall'uso di un byte o di un cortocircuito. Ciò non significa che non dovresti usarlo in quanto è un modo per far sì che tu e altri conosciate l'intervallo di dati che questo valore dovrebbe avere.

Ora, come dicevo si potrebbe effettivamente memorizzare 32 booleane in un singolo intero effettuando le seguenti operazioni:

int many_booleans = -1; //All are true; 
int many_booleans = 0; //All are false; 
int many_booleans = 1 | 2 | 8; //Bits 1, 2, and 4 are true the rest are false; 

Così ora una breve consiste di 16 bit in modo da 16 + 16 = 32 che si inserisce perfettamente all'interno di un Numero intero a 32 bit. Quindi ogni valore int può essere costituito da 2 valori brevi.

int two_shorts = value | (value2 << 16); 

Allora, cosa di cui sopra sta facendo è il valore è qualcosa tra -32768 e 32767 o come valore senza segno 0 - 65535. Quindi diciamo che il valore è pari a -1 in modo come un valore senza segno era 65535. Ciò significherebbe i bit da 1 a 16 sono attivati, ma quando si esegue effettivamente la matematica consideriamo il range 0 - 15.

Quindi dobbiamo attivare i bit 17 - 32. Quindi dobbiamo iniziare a qualcosa di più grande di 15 bit. Quindi iniziamo a 16 bit. Quindi prendendo value2 e moltiplicandolo per 65536 che è ciò che fa "< < 16". Ora avremmo diciamo valore2 pari a 3 sarebbe in OR = 3x65536 196608. Così il nostro valore intero sarebbe pari 262143.

int assumed_value = 262143; 

quindi diciamo che vogliamo recuperare i due valori a 16 bit interi.

Inoltre, in pratica, si pensa agli operatori bit a bit come a 2. Il vero è tutto ciò che realmente sono. Non guardare mai termini di 0 e di 1. L'ho pubblicato per lo più per aiutare chiunque possa imbattersi in questa ricerca di array a corto raggio o anche eventualmente multidimensionali. Se ci sono errori di battitura, mi scuso, ho scritto rapidamente.

2

Da DataInputStream.java

public final int readUnsignedShort() throws IOException { 
    int ch1 = in.read(); 
    int ch2 = in.read(); 
    if ((ch1 | ch2) < 0) 
     throw new EOFException(); 
    return (ch1 << 8) + (ch2 << 0); 
} 
0

Se si utilizza una libreria di terze parti è un'opzione, non v'è jOOU (uno spin off libreria da jOOQ), che offre tipi di wrapper per numeri interi senza segno in Java. Questo non è esattamente la stessa cosa di avere il tipo primitivo (e quindi il codice byte) supporto per i tipi non firmati, ma forse è ancora abbastanza buono per il tuo caso d'uso.

import static org.joou.Unsigned.*; 

// and then... 
UShort s = ushort(1); 

(Disclaimer: io lavoro per l'azienda dietro a queste librerie)

Problemi correlati