Mam dwie zmienne (test1
i test2
), oba niepodpisane. Muszę sprawdzić, który z nich jest większy.odejmowanie między wartościami bez znaku - nieoczekiwany wynik
Próbuję zrozumieć, co się stanie, jeśli wystąpi przepełnienie.
Moja pierwsza próba została wykonana z uint8_t typu danych (char):
#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;
}
wyjściowa:
test1 = 0
test2 = 255
test1 - test2 = 1
test1 < test2
test1 > test2
Co? Odejmowanie i zapisywanie w zmiennej, a następnie sprawdzanie, to inne niż sprawdzanie odejmowania w locie?
Drugie badanie przeprowadzono z uint32_t (długi) typu danych:
#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;
}
wyjściowa:
test1 = 0
test2 = 4294967295
test1 - test2 = 1
test1 > test2
test1 > test2
Co ??? Teraz odejmowanie i zapisywanie w zmiennej, a następnie sprawdzanie, to tak samo jak sprawdzanie odejmowania w locie?
SO Spodziewałem się, że odejmowanie między wartościami unsigned (bez wyraźnego cast) zawsze zwraca wartość> = 0. ale robi odejmowanie wewnątrz IF prowadzi do nieoczekiwanych rezultatów.
Teraz jestem zdezorientowany. Czy ktoś może wyjaśnić mi to zachowanie?
W trzeciej linii w treści głównej: 'uint8_t test2 = pow (2, 8 * sizeof (test1)) - 1; 'to nie jest naprawdę sensowne, jeśli weźmiesz 2 do potęgi' 8 * sizeof (test1) ', to przepełni' uint8_t' i uzyska wartość zero. Ponieważ jest niepodpisany, przepełnienie zawsze ma dobrze zdefiniowane wartości. Zamiast tego należy zamiast tego napisać "-1", dla jasności. –
Robisz to bardzo ciężko - czy uważasz, że to pytanie można uprościć do samego przypisania testu 1 i testu 2, a następnie przykłady wyrażeń, które dają oczekiwany wynik, nie oczekuj? Wydaje się, że jest tu zbyt dużo niepotrzebnego kodu. – Clifford
@ChrisBeck: lub 'uint8_t test1 = ~ 0;' a następnie przypisanie wartości ujemnej do typu bez znaku, lub jeszcze lepiej użyj 'UCHAR_MAX' lub' std :: numeric_limits :: max() ' –
Clifford