Dlaczego procesor nie dzieli z resztą przez zero, a kalkulator windowsa tak ?

0

Pytanie z pozoru oczywiste ale chyba nie do końca.

Dlaczego kalkulator windows honoruje przemienne dzielenie modulo
np 1 % 0 = 1, 0 % 1 = 0, 2 % 0 = 2 ale 0 % 2 = 0 - natomiast komputer nie potrafi tego policzyć albo coś ja źle robię ? - oto kod

int main()
{
    QVector<int> line1{0,0,3,0,5,0,7,8,0,0};

    QVector<int> data{1,2,3,4,5,6,7,8,9,10};

    for(int i=0; i<data.size(); ++i){
        if(data.at(i) % line1.at(i) != 0){
            qDebug()<< data.at(i);
        }
    }

    return 0;
}

w całym tym kodzie wynik chcę uzyskać taki -> 1, 2, 4, 6, 9, 10 dlatego jak policzyłem na kalkulatorze i ładnie działało, to było ok, ale komp tego zabrania - wiem, że nie ma dzielenia przez zero, ale kurna dzielenie modulo bardzo się przydaje do różnych rzeczy.

z problemem sobie poradziłem i w warunku zamiast % napisałem != ale temat nadal jest aktualny i czeka na wyjaśnienie. Jak to jest rozwiązane w zwykłym kalkulatorze, a procesor sobie z tym nie radzi ?

6

Arithmetic operators - cppreference.com

The binary operator / divides the first operand by the second (after usual arithmetic conversions).

For integral operands, it yields the algebraic quotient. The quotient is truncated towards zero (fractional part is discarded).

If the second operand is zero, the behavior is undefined, except that if floating-point division ... .
....
The binary operator % yields the remainder of the integer division of the first operand by the second (after usual arithmetic conversions; note that the operand types must be integral types). If the quotient a / b is representable in the result type, (a / b) * b + a % b == a. If the second operand is zero, the behavior is undefined.

7

przykładowo, architektura x86 nie ma czegoś takiego jak operacja modulo (przynajmniej dla liczb całkowitych nie pamiętam czegoś takiego). jest dzielenie z resztą, czyli dzielenie + modulo (tzn. zawsze naraz), a wiadomo, że nie dzieli się przez 0 :) dla liczb całkowitych dzielenie przez 0 skutkuje błędem, dla liczb zmiennoprzecinkowych skutkuje wynikiem typu not-a-number.

kalkulator windowsowy może zawierać w środku ifologię do obsługi dowolnych przypadków nieobsługiwanych bezpośrednio przez procesor.

0

ok, dzięki - czyli nie można podzielić zero przez coś - tak, wiem, zero to zero ale zdziwiło mnie, że w kalkulatorze działa i tego dzielenia akurat potrzebuję, bo dzielenie modulo wbrew pozorom ma olbrzymią ilość zastosowań aby np uprościć jakiś alogrytm

2

Myślę że powinieneś zacząć od podstaw bo nie ma czegoś takiego jak "przemienne dzielenie". Co do samego dzielenia przez zero, to nie jest tak że cpu sobie z tym nie radzi. Jest to po prostu sprawdzane przez ide, kompilator i system by nie próbowac wykonać takiego działania, gdyż nie ma ono sensu. To jest coś na zasadzie pytania ile 0 mieści się w 1 (wynikiem jest nieskończoność) i oczekujesz że procesor poda ci konkretną wartość. Będzie próbował to policzyć dopóki nie braknie mu zasobów co będzie skutkować 'zawieszeniem programu' i finalnie jego wysypaniem.

0

To jest undefinied behavior czyli nie wiadomo co się stanie i każdy kompilator a potem architektura procesora może inaczej to obsługiwać. Kalkulator Windowsa nie wiadomo w czym w ogóle został napisany. Jak w c++ to pewnie skomplikowany przez msvc i to możliwe, że są tam jakieś ify, które to obsługuja.

1

Dlaczego procesor nie dzieli z resztą przez zero

Bo się nie da.

, a kalkulator windowsa tak ?

Bo ktoś w microsofcie stwierdził, że to jest ładniej, bardziej zrozumiale dla niektórych, whatever. W każdym razie ta decyzja jest w 100% nietechniczna i niematematyczna.

3

Kalkulator Windowsa (10 i 11) jest open-source i napisany w C++ (i C#), możesz sobie zanalizować, dlaczego tak działa, jak działa: https://github.com/microsoft/calculator

0

i każdy kompilator a potem architektura procesora może inaczej to obsługiwać to implementation defined behavior, undefined jest gorsze - ten sam kompilator na tej samej architekturze może DOWOLNIE zareagować, inaczej za każdym razem i z pozoru bez sensu. Nawet może zastąpić cały program przez rm -rf /

2

W ogóle idea obliczenia coś % 0 wydaje się być matematycznie nie poprawna. Jeśli nie możemy czegoś podzielić przez zero, to jak mamy określić resztę z takiego dzielenia? Podstawówka i zloty wierszyk: "nigdy cholero nie dzieł przez zero".
Zobacz np. na woframalfa:
https://www.wolframalpha.com/input?i=5%250
Wynik nieokreślony.
Nie sugeruj się kalkulatorem tylko podstawami matematyki.
IMHO takie działanie bardziej powinno zwaracać Division by zero niż dawać 0 jako wynik.

Czyli IMHO Twój program też nie powinien dopuścić do sytuacji gdzie takie obliczenia mogą mieć miejsce.

0

Nie strasz

0

Gdzieś na necie jest fajny przykład jak za pomocą UB można wywołać funkcję, która nigdzie w kodzie nie jest wywoływana. ;)

0

ogólnie do wszystkich powiem jedno - widzę, że wraz ze wzrostem dyskusji za chwilę znajdzie się wykładnia analizy matematycznej z waszej strony (chociaż szczerze wątpię by ktoś z was był na poziomie np Banacha) i będziecie obrastać w piórka jacy to jesteście ah i oh bo wiecie, że "czegoś tam nie można", a w rzeczywistości wasza wiedza na tym się kończy (już widzę jak fochacie jak panienki) ale do rzeczy.

Nie wiem czy czytaliście uważnie ale pisałem, że wiem, że nie ma dzielenia przez zero - tyle. Sądziłem, że wasze wprawne oko powinno zauważyć, że chciałem tą niedogodność dzielenia przez zero wykorzystać na swoją korzyść aby po prostu otrzymać oczekiwany wynik (uprzednio sprawdzając na kalkulatorze) i te obliczenia nawet przytoczyłem w poście, więc trochę nie rozumiem waszego niezrozumienia treści posta i odnoszę wrażenie, że sądzicie, że nie wiem, że dzielić zera się nie da... zero to nic, a nic, to nic, więc nic nie da się podzielić bo nic to nic xD tylko sądziłem, że komputer będzie trochę głupszy i łyknie mój patent, a tu pomyłka. Dlatego chciałem zapytać czy wszystko robię dobrze, bo dzielenie modulo naprawdę przydaje się w algorytmach (wcześniej sądziłem że jest bezużyteczne ale kilka razy bardzo mi się to przydało)

1
zkubinski napisał(a):

Nie wiem czy czytaliście uważnie ale pisałem, że wiem, że nie ma dzielenia przez zero - tyle. Sądziłem, że wasze wprawne oko powinno zauważyć, że chciałem tą niedogodność dzielenia przez zero wykorzystać na swoją korzyść aby po prostu otrzymać oczekiwany wynik (uprzednio sprawdzając na kalkulatorze) i te obliczenia nawet przytoczyłem w poście

Całe te rozumowanie o kant tyłka możesz sobie potłuc. Uczyłeś się na matematyce dowodzenia różnych rzeczy? Miałeś logikę? Jeśli tak, to musisz wiedzieć, że wykorzystując błędne operacje/założenia (a takim jest zakładanie, że da się wykonać operację x mod 0) dojdziesz do fałszywych wniosków. Temu nikt Cię nie rozumie to jest podstawowa wiedza jaką każdy inżynier posiadać powinien. Po prostu podczas obliczeń nie możesz wykorzystywać nieprawdziwych rzeczy, bo dojdziesz do steku bzdur. Zatem podsumowując:

zkubinski napisał(a):

Dlatego chciałem zapytać czy wszystko robię dobrze, bo dzielenie modulo naprawdę przydaje się w algorytmach (wcześniej sądziłem że jest bezużyteczne ale kilka razy bardzo mi się to przydało)

Nie, nie robisz dobrze...

0

niekoniecznie masz rację, pamiętam, że robiłem jakiś algorytm i w tym algorytmie wykorzystywałem na swój sposób bodajże typ int chodziło o to aby obciąć wynik zmiennoprzecinkowy i zostawić tą część która jest całością. Więc byłbym dużo ostrożny z tezami, że Uczyłeś się na matematyce dowodzenia różnych rzeczy? Miałeś logikę? robiąc coś niby logicznie, to często w niektórych algorytmach trzeba po prostu robić nielogicznie i jakby wykorzystywać pewne właściwości różnych obiektów na swój sposób

2

"aby obciąć wynik zmiennoprzecinkowy i zostawić tą część która jest całością" - wystarczy floor(x) lub fmod(x,1) w zależności jak chcesz traktować liczby ujemne.

2
zkubinski napisał(a):

niekoniecznie masz rację, pamiętam, że robiłem jakiś algorytm i w tym algorytmie wykorzystywałem na swój sposób bodajże typ int chodziło o to aby obciąć wynik zmiennoprzecinkowy i zostawić tą część która jest całością.

Pytanie tylko z jakiego powodu tak zrobiłeś? Oczywiście można jeść zupę za pomocą widelca, ale po co i w jakim celu? Narzędzia dobiera się odpowiednio do zastosowań. A w kodzie produkcyjnym nie ma miejsc na takie haki.

zkubinski napisał(a):

Więc byłbym dużo ostrożny z tezami, że Uczyłeś się na matematyce dowodzenia różnych rzeczy? Miałeś logikę? robiąc coś niby logicznie, to często w niektórych algorytmach trzeba po prostu robić nielogicznie i jakby wykorzystywać pewne właściwości różnych obiektów na swój sposób

Poproszę o przykłady, które to algorytmy są nielogiczne, bo jak na razie to tylko takie machanie rękoma. Takie podejście 'stosowania czegoś na swój sposób' jest słabe. Teraz możesz pamiętać, za rok już niekoniecznie i potem będziesz się głowił "co artysta miał na myśli". Co więcej możesz trafić w pracy na dzieło tak myślącego artysty którego już dawno w firmie nie ma, w konsekwencji takich radosnych twórczości trzeba rozszyfrowywać błahe rzeczy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1