Ho due variabili (test1
e test2
), entrambe non firmate. Ho bisogno di controllare quale di loro è più grande.sottrazione tra valori non firmati - risultato imprevisto
Sto cercando di capire cosa succede se si verifica un overflow.
Il mio primo test è stato fatto con uint8_t (char) tipo di dati:
#include <stdio.h>
#include <stdint.h>
#include <math.h>
int main()
{
uint8_t test1 = 0;
printf("test1 = %d\n", test1);
uint8_t test2 = pow(2, 8 * sizeof(test1)) - 1; //max holdable value of uint8_t
printf("test2 = %d\n", test2);
uint8_t test3 = test1 - test2;
printf("test1 - test2 = %d\n", test3);
if ((test1 - test2) == 0)
printf("test1 == test2\n");
if ((test1 - test2) > 0)
printf("test1 > test2\n");
if ((test1 - test2) < 0)
printf("test1 < test2\n");
if (test3 == 0)
printf("test1 == test2\n");
if (test3 > 0)
printf("test1 > test2\n");
if (test3 < 0)
printf("test1 < test2\n");
return 0;
}
uscita:
test1 = 0
test2 = 255
test1 - test2 = 1
test1 < test2
test1 > test2
Cosa? Effettuare la sottrazione e salvarla in una variabile, quindi verificarla, è diversa da controllando la sottrazione al volo?
mio secondo test è stato fatto con uint32_t (lungo) tipo di dati:
#include <stdio.h>
#include <stdint.h>
#include <math.h>
int main()
{
uint32_t test1 = 0;
printf("test1 = %d\n", test1);
uint32_t test2 = pow(2, 8 * sizeof(test1)) - 1; //max holdable value of uint32_t
printf("test2 = %lu\n", test2);
uint32_t test3 = test1 - test2;
printf("test1 - test2 = %d\n", test3);
if ((test1 - test2) == 0)
printf("test1 == test2\n");
if ((test1 - test2) > 0)
printf("test1 > test2\n");
if ((test1 - test2) < 0)
printf("test1 < test2\n");
if (test3 == 0)
printf("test1 == test2\n");
if (test3 > 0)
printf("test1 > test2\n");
if (test3 < 0)
printf("test1 < test2\n");
return 0;
}
uscita:
test1 = 0
test2 = 4294967295
test1 - test2 = 1
test1 > test2
test1 > test2
Cosa ??? Ora effettuare la sottrazione e salvarla in una variabile, quindi controllarla, è uguale a controllando la sottrazione al volo?
SO mi aspettavo che la sottrazione tra i valori senza segno (senza un cast esplicito) restituisce sempre un valore> = 0. Ma fare la sottrazione all'interno della IF porta a risultati inaspettati.
Ora sono confuso. Qualcuno può spiegarmi questo comportamento?
Alla 3a riga nel corpo principale: 'uint8_t test2 = pow (2, 8 * sizeof (test1)) - 1; 'questo non è molto sensato, se si prende 2 alla potenza' 8 * sizeof (test1) ', questo supererà un' uint8_t' e otterrà il valore zero. Poiché non è firmato, l'overflow ha sempre valori ben definiti. Quindi, invece di scrivere questo, dovresti invece scrivere '-1', per chiarezza. –
Stai facendo un lavoro molto duro - pensi che questa domanda potrebbe essere semplificata solo all'assegnazione del test 1 e del test 2, quindi esempi di espressioni che producono il risultato che ti aspetti non si aspettano? Sembra che ci sia una grande quantità di codice superfluo da attraversare qui. – Clifford
@ChrisBeck: o 'uint8_t test1 = ~ 0;' piuttosto che assegnare un valore negativo a un tipo senza segno, o meglio ancora usare 'UCHAR_MAX' o' std :: numeric_limits :: max() ' –
Clifford