Na przykład,
int result;
result = 125/100;
lub
result = 43/100;
Czy wynikiem będzie zawsze podłoga dywizji? Jakie jest zdefiniowane zachowanie?
"I just throw the dam fraction part in the trash and move on with life"
Na przykład,
int result;
result = 125/100;
lub
result = 43/100;
Czy wynikiem będzie zawsze podłoga dywizji? Jakie jest zdefiniowane zachowanie?
"I just throw the dam fraction part in the trash and move on with life"
Odpowiedzi:
Czy wynikiem będzie zawsze podłoga dywizji? Jakie jest zdefiniowane zachowanie?
Tak, iloraz całkowity dwóch operandów.
6.5.5 Operatory multiplikatywne
6 Po podzieleniu liczb całkowitych wynikiem operatora / jest iloraz algebraiczny z odrzuconą dowolną częścią ułamkową. 88) Jeżeli iloraz a / b jest reprezentowalny, wyrażenie (a / b) * b + a% b będzie równe a.
i odpowiedni przypis:
88) Jest to często nazywane „obcięciem do zera”.
Oczywiście należy zwrócić uwagę na dwa punkty:
3 Zwykłe konwersje arytmetyczne są wykonywane na operandach.
i:
5 Wynikiem operatora / jest iloraz podziału pierwszego operandu przez drugi; wynikiem operatora% jest reszta. W obu operacjach, jeśli wartość drugiego operandu wynosi zero, zachowanie jest niezdefiniowane.
[Uwaga: moje podkreślenie]
(a / b) * b + a % b == a
trzeba było spełnić, a wartość bezwzględna a % b
musiała być mniejsza niż a
, ale czy a % b
była ujemna dla ujemnej a
czy b
nie została określona.
Dirkgently daje doskonały opis podziału liczb całkowitych w C99, ale powinieneś także wiedzieć, że w C89 dzielenie liczb całkowitych z argumentem ujemnym ma kierunek zdefiniowany przez implementację.
Z projektu ANSI C (3.3.5):
Jeśli któryś z argumentów jest ujemny, to czy wynik operatora / jest największą liczbą całkowitą mniejszą niż iloraz algebraiczny, czy też najmniejszą liczbą całkowitą większą niż iloraz algebraiczny, określa się implementację, podobnie jak znak wyniku operatora%. Jeżeli iloraz a / b jest reprezentowalny, wyrażenie (a / b) * b + a% b będzie równe a.
Uważaj więc na liczby ujemne, gdy utkniesz przy kompilatorze C89.
To zabawne, że C99 wybrał obcięcie w kierunku zera, bo tak właśnie zrobił FORTRAN. Zobacz tę wiadomość na comp.std.c.
reliable integer division
o nowej funkcji językowej. Niesamowite *-*
.
expr1 / expr2
i expr1 % expr2
musi być ze sobą spójne, gdy oba przypadki expr1
łączą te same obiekty w ten sam sposób, i podobnie expr2
, ale wybór podziału obciętego na zmienny jest inaczej nieokreślony. Które pozwoliłyby bardziej efektywne generowanie kodu bez zerwania dużo kompatybilność (i implementacje mogłyby udokumentować specyficzne zachowanie jeżeli nachylona)
Tam, gdzie wynik jest ujemny, C skraca się w kierunku 0 zamiast podłogi - nauczyłem się tego czytania o tym, dlaczego podział liczb całkowitych w Pythonie zawsze ma podłogę tutaj: dlaczego podłogi w liczbach całkowitych w Pythonie
filtered = (k - 1) * filtered + value + carry; carry = filtered % factor; filtered /= factor
iteracja ze zmieniającymi się wartościami value
. Jest to dobre przybliżenie liczb całkowitych do filtra dolnoprzepustowego pierwszego rzędu ze stałą czasową k
... ale jest symetryczne tylko wtedy, gdy podział jest obcinany i carry
otrzymuje wartości ujemne. Oba zachowania przy podziale przydają się od czasu do czasu.
div
jest operatorem dzielenia zmiennoprzecinkowego i factor
jest nieparzysty, to filtered += (filter+(factor div 2)) div factor
dałby czyste i symetryczne zachowanie dla wszystkich wartości do INT_MAX-(factor div 2)
.
Tak, wynik jest zawsze przycinany do zera. Zaokrągli się w kierunku najmniejszej wartości bezwzględnej.
-5 / 2 = -2
5 / 2 = 2
W przypadku niepodpisanych i nieujemnych wartości ze znakiem jest to to samo co floor (zaokrąglenie w kierunku -Infinity).
Czy wynikiem będzie zawsze podłoga dywizji?
Nie. Wynik jest różny, ale zmiana występuje tylko w przypadku wartości ujemnych.
Jakie jest zdefiniowane zachowanie?
Aby wyczyścić podłogę, zaokrągla się w kierunku ujemnej nieskończoności, podczas gdy podział na liczby całkowite zaokrągla w kierunku zera (obcina)
Dla wartości dodatnich są takie same
int integerDivisionResultPositive= 125/100;//= 1
double flooringResultPositive= floor(125.0/100.0);//=1.0
W przypadku wartości ujemnej jest inaczej
int integerDivisionResultNegative= -125/100;//=-1
double flooringResultNegative= floor(-125.0/100.0);//=-2.0
Wiem, że ludzie odpowiedzieli na twoje pytanie, ale w sposób laicki:
5 / 2 = 2
// ponieważ zarówno 5, jak i 2 są liczbami całkowitymi, a dzielenie liczb całkowitych zawsze obcina miejsca po przecinku
5.0 / 2 or 5 / 2.0 or 5.0 /2.0 = 2.5
// tutaj albo 5, albo 2 albo oba mają dziesiętne, stąd iloraz, który otrzymasz, będzie dziesiętny.