2010-06-12 29 views
7

In C++ possiamo rendere primitive unsigned. Ma sono sempre positivi. C'è anche un modo per creare variabili negative non firmate? So che la parola senza segno significa "senza segno", quindi anche non un segno meno (-). Ma penso che C++ debba fornirlo.Primitive negative senza segno?

+0

"unsigned" in C/C++ è davvero un sinonimo per non negativo. –

+13

Supponiamo che rappresentino numeri negativi. – AraK

+1

Interessante domanda che non ho mai sentito prima. Sfortunatamente la risposta è no." –

risposta

4

No. unsigned può contenere solo numeri non negativi.

Se è necessario un tipo che rappresenta solo numeri negativi, è necessario scrivere una classe da soli o semplicemente interpretare il valore come negativo nel programma.

(Ma perché avete bisogno di un tale tipo?)

+0

Quindi, se voglio davvero questo, dovrò creare la mia classe e fare un po 'di overloading dell'operatore per simulare un numero negativo? –

+0

@KennyTM: se voglio usare meno memoria possibile. –

+1

@Martijn: Sembra un'ottimizzazione prematura. Quanti di questi numeri hai bisogno? Qual è la gamma di quei numeri? – kennytm

2

unsigned interi sono solo positivi. Da 3.9.1 comma 3 dello standard 2003, C++:

L'intervallo di valori negativi di tipo intero con segno è un sottoinsieme di senza segno tipo intero corrispondente, e la rappresentazione di valore ciascuna corrispondente firmata/unsigned tipo deve essere lo stesso.

Lo scopo principale dei tipi di numeri interi senza segno è supportare l'aritmetica modulo. Da 3.9.1 paragrafo 4:

interi senza segno, dichiarato senza segno, deve rispettare le leggi dell'aritmetica modulo 2 n dove n è il numero di bit nella rappresentazione valore di quel particolare dimensione di numero intero.

Sei libero, naturalmente, di considerarli negativi se lo desideri, devi solo tenerne traccia in qualche modo (magari con una bandiera booleana).

0

Penso che tu stia pensando nel modo sbagliato.

Se si desidera un numero negativo, non è necessario dichiarare la variabile come non firmata.

Se il problema è l'intervallo di valori e si desidera un altro bit, è possibile utilizzare un tipo di dati "più grande" (int 64 per esempio ...).

Quindi se si utilizza il codice legacy, la creazione di una nuova struttura può risolvere il problema, ma in questo modo a causa della situazione specifica, C++ non deve gestirlo.

0

Non fatevi ingannare dal nome: non firmati è spesso frainteso come non-negativo, ma le regole per la lingua sono diverse ... probabilmente un nome migliore sarebbe stato "bitmask" o "modulo_integer".

Se pensate che non firmato sia non negativo, allora per esempio le regole di conversione implicite sono assurdità totale (perché una differenza tra due non negativi dovrebbe essere un non-negativo? Perché l'aggiunta di un non-negativo e un intero dovrebbe essere non negativo?).

È molto spiacevole che la stessa libreria standard C++ sia caduta in quel fraintendimento perché ad esempio vector.size() non è firmata (assurdo se si intende come linguaggio in termini di bitmask o modulo_integer).Questa scelta per le dimensioni ha più a che fare con i vecchi tempi di 16 bit che con quelli senza segno ed è stata a mio parere una scelta terribile che stiamo ancora pagando come bug.

+2

Quali vantaggi offre la firma di vector.size()? Non può mai restituire un valore negativo. Esattamente quali bug si presentano a causa della firma/non firmati? È un concetto piuttosto semplice da affrontare. – Puppy

+0

Il bug più comune che ho osservato è iterando da 0 a vector.size() - 1 che per un vettore vuoto è un numero enorme. Altri possibili bug nascono dal fatto che a - b> 0 non è uguale a a> b. Si noti che tutto ciò accade perché non firmato per C++ significa più o meno "elemento di Z [n]" (Z [n] = interi modulo n) e non ha nulla a che fare con il segno. Secondo te, ha senso che il numero di elementi in un vettore sia un elemento di quell'anello? Gli input non firmati sono davvero IMO molto utili ... ma NON come quantità. – 6502

+1

OK, quindi ottieni un valore inaspettato. Come è meglio che ottenere un underflow? Almeno in questo modo non stai distruggendo la tua memoria. –

0

Ma penso che C++ deve fornirlo.

Perché? Pensi che il C++ debba fornire la capacità di rendere negativi i numeri non negativi? È sciocco.

I valori non firmati in C++ sono definiti per essere sempre non negativi. Si avvolgono intorno allo — invece che a underflow — a zero! (E lo stesso all'altro estremo della gamma)