Modulo dodatnie C# (Dodatnia reszta z dzielenia)

By | 5 kwietnia 2015

Dzielenie z resztą w C# może zwracać wynik ujemny, co jest dość zaskakujące, ponieważ gryzie się z tym, czego uczyłem się na uczelni, czy w technikum. Tak więc, aby poprawić ten… błąd (?) napisałem krótki kod. Oczywiście mógłbym za każdym razem sobie coś takiego szybko napisać, ale co by było gdybym się pomylił, a tutaj jest pewny kod. Korzystajcie 🙂

[csharp]
int modulo_dodatnie(int liczba, int modulo)
{
    return (liczba % modulo + modulo) % modulo;
}
[/csharp]

2 thoughts on “Modulo dodatnie C# (Dodatnia reszta z dzielenia)

  1. Kilka_uwag

    Kilka uwag dla bardziej dociekliwych 😉 :

    – Dzielenie z resztą z punktu widzenia matematyki może dać wynik ujemny (podobnie jak dzielenie zwykłe 😉 ). Wystarczy, ze dzielna i dzielnik będą przeciwnego znaku – jest to sytuacja całkowicie normalna.

    Twoje rozwiązanie jest ok, ale można je poprawić. Na kilku płaszczyznach:

    – Po pierwsze – twoje rozwiązanie zawiera dwie operacje modulo i dodawanie. Operacja modulo jest kosztowna z punktu widzenia złożoności obliczeniowej (porównując do innych operacji), dlatego można zastosować np. działanie:
    liczba * liczba % modulo
    Mamy jedno działanie modulo i jedno mnożenie. Kosztem oczywiście niższego zakresu

    – Po drugie – aż prosi się tutaj, aby przeciążyć operator ;). Chyba, że chcemy zachować możliwość normalnego liczenia modulo (z wartościami ujemnymi).

    – Po trzecie – w takim przypadku jak u Ciebie dużo wygodniejsze będzie tutaj zastosowanie Extensions methods a nie funkcji. Przykład:

    static void Main(string[] args)
    {
    int a = -5;
    Console.WriteLine(a.moduloDodatnie(3));
    Console.ReadKey();
    }

    public static class IntExtension
    {
    public static int moduloDodatnie(this int liczba, int modulo)
    {
    return (liczba * liczba % modulo);
    }
    }

    Rozszerzyliśmy typ int o metodę moduloDodatnie – w ten sposób dla każdego obiektu int dostępna jest „wbudowana” metoda moduloDodatnie.

    – I wreszcie po czwarte – wynik modulo nie musi być liczbą całkowitą (podobnie jak czynniki). Dlatego tutaj powinno się iść w coś w stylu:

    public static T moduloDodatnie(T liczba, T modulo) where T : IArithmetic
    {
    return (T)Convert.ChangeType(liczba%modulo , typeof(T));
    }
    czy nawet rozróżnienie typów liczba/modulo (bo mogą być różne).
    Ostatecznie można po prostu napisać uniwersalną metodę/przeładowanie operatora dla wartości zmiennoprzecinkowych i rzutować int do tych wartości.

    Reply
    1. Paweł Trojanowski Post author

      Zwykle piszę algorytmy w taki sposób, żeby ktoś z małymi umiejętnościami programistycznymi mógł zrozumieć co się dzieje, dlatego nie używam żadnych bardziej skomplikowanych konstrukcji programistycznych.

      Dzięki za komentarz, bo bardzo rozszerza mój wpis 🙂 Po kilku latach od napisania tego wpisu, muszę się zgodzić z Tobą w 100% 🙂

      Reply

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *