Polecam

.NET Blogs PL
CodeGuru


Challenge: Jak napisać to inaczej?

August 10, 2010 in categories: pro by Gutek

14

Naprawdę krótko, jak napisać poniższy kod inaczej nie wykorzystując modulo (%)?

public static class IntEx
{
    public static bool IsEven(this int value)
    {
        return value % 2 == 0;
    }

    public static bool IsOdd(this int value)
    {
        return !value.IsEven();
    }
}

Aha, nie chodzi o rozbicie metod na klasy, extension methods itp. :)




 

 

 

14 comments for "Challenge: Jak napisać to inaczej?"

  1. Gekon
    Gekon Says:

    public static class IntEx
    {
        public static bool IsEven(this int value)
        {
            return (value & 1) == 0;
        }

        public static bool IsOdd(this int value)
        {
            return (value & 1) == 1;
        }
    }

    Z testow ktore wykonalem to rozwiazanie jest o jakies 5% szybsze. Dodatkowo w twojej wersji IsOdd wykonuje jedno operacje wiecej, zaprzeczenie IsEven().

    • Gutek
      Gutek Says:

      no i jaki jest sens robienia chanllenge Smile Wlasnie o to mi chodzilo. brawo Smile

    • Gutek
      Gutek Says:

      Male wytlumaczenie dla tych, ktorzy by sie zastanawiali dlaczgeo & 1 dziala. Jest to tak naprawde zrobienie operacji logicznego and na ostatnim bitcie liczby. Jezeli nasza licza to 10 czyli: 1010 w systemie binarnym to mamy

      1010      (10)
      0001 AND  (1)
      0000 =

      dla liczby 11 (1011):

      1011      (11)
      0001 AND  (1)
      0001 =

      wiec za pomoca & mozemy napisac kod sprawdzajacy czy liczba jest parzysta lub nie parzysta troche szybciej niz wykorzystujac modulo.

  2. Paweł
    Paweł Says:

    Ja szczerze mam nadzieję, że nikt się nie zastanawia dlaczego to działa. To są podstawy podstaw...oraz oczywista oczywistość Smile

    Pozdrawiam,
    Paweł

    • Gekon
      Gekon Says:

      Oj. Z tymi slowami to bym uwazal. Wczoraj poruszalem ten temat ze znajomymi "koderami" i kilku z nich nie potrafilo powiedziec do czego dokladnie sluzy operator &. Sczerze mowiac w pracy jedyne zastosowanie do tego operatora znalazlem w maskowaniu enumeracji (nic wiecej nie przychodzi mi do glowy). Ale zeby tak wogole nie wiedziec jak to dziala to chyba troche wstyd Laughing

      • Leszcz
        Leszcz Says:

        Może i wstyd, ale ja mimo iż wiem jak to działa, to wolałbym nie widzieć takiego kodu. Dla mnie 90% wartości kodu to jego czytelność, a zdecydowanie prościej czyta mi się rozwiązanie, które Gutek napisał w treści tego zadania.
        Inna sprawa tutaj jest taka, że akurat te funkcje są skrajnie proste i nazwy są oczywiste, więc pewnie nawet bym nie zajrzał, ale równocześnie takie pisanie powoduje, że programiści mają ochotę pisać tak gdzie indziej, a ja mam ochotę udusić za każdym razem jak coś takiego czytam.

  3. leszcz
    leszcz Says:

    A ja mam szczerą nadzieję, że nikomu nie przychodzi do głowy tak pisać, chyba że jest to najczęściej wywoływana funkcja, która po prostu musi być super hiper w kosmos wydajna.

  4. Mateusz Kierepka
    Mateusz Kierepka Says:

    Można jeszcze tak (jak ktoś chciałby inaczej niż powyżej ;))
    Tak czy siak operacja na bitach piwinna być najszybsza i też tak bym napisał ;)
    [...]
        public static bool IsEven(this int value)
        {
            var remainder =0;
            Math.DivRem(value, 2, out remainder);
            return  remainder == 0;
        }
    [...]

    • Gekon
      Gekon Says:

      Reflector powiada ze Math.DivRem korzsta z modulo:

      public static int DivRem(int a, int b, out int result)
      {
          result = a % b;
          return (a / b);
      }

  5. ...
    ... Says:

    No operatora & ja używam do ... tworzenia wszystkich podzbiorów danego zbioru Smile
    Nie znam zbytnio C# (tylko podstawy), ale wygląda to mniej więcej tak:

    const int elements = 10;

    for(int i = 0; i < pow(2.0f, n) - 1; ++i){
       for(int j = 0; j < elements; ++j)
          if(j & i) write(j);
       write("\n");
    }

    • Gekon
      Gekon Says:

      W C# warunek nie zadziala, wynik dzialania typA & typB daje typA, wiec w tym przypadku if dla int nie zadziala. Ale chyba chodzilo o to:

      for (int i = 0; i < Math.Pow(2.0f, n) - 1; ++i)
      {
            for (int j = 0; j < elements; ++j)
                   if ((j & i) == i) Console.Write(j);
            Console.WriteLine();
      }

      • ...
        ... Says:

        faktycznie w C# trzeba jawnie definiować warunki (nie to co c++), ale się rozpędziłem i zły kod dałem warunek powinien być taki :

        if( i & (1 << j) == 1)

        1 << j to przesunięcie bitowe (nie wiem czy w C# jest), czyli 2 do potęgi j

        • Gutek
          Gutek Says:

          jak najbardziej w C# tez sa przesuniecia bitowe, nie ma tylko operacji dostepnej w Java >>> Unsigned right shift.

Comments are closed

© 2008-2010 Jakub Gutkowski. Powered by BlogEngine.NET 1.5.1.14. Hosted on OrcsWeb.

Design