wtorek, 8 grudnia 2015

Dlaczego język C# nie posiada operatora potęgowania

Powyższe pytanie przyszło mi jakiś czas temu do głowy, kiedy już znalazłem powód, dlaczego operacja zapisana jako:

int y = a^c;

nie dawała rezultatu zgodnego z oczekiwaniem.
Dla wyjaśnienia, w języku C# operator "^" jest operatorem logicznym XOR więc powyższy kod jest, z punktu widzenia kompilatora, poprawny.

Po zadaniu tego pytania jedynie słusznej wyszukiwarce internetowej, w wynikach pojawił się post z bloga MSDN - który wyjaśnia tę ciekawą sytuację (w wolnym tłumaczeniu):


Niektóre języki programowania udostępniają operator potęgowania, więc działanie może być zapisane jako:

float result = value^2;

zamiast wywoływania funkcji [potęgowania]. Nie mamy czegoś takiego w C#.

Możliwe byłoby dodanie do języka operatora potęgowania, ale w wielu programach taka operacja jest wywoływania niezmiernie rzadko i nie wydaje się być to uzasadnione, kiedy łatwo jest wywołać funkcję Math.Pow().

Dodatkowo martwię się nieco o implementację takiego operatora. Większość kompilatorów przetłumaczy powyższy przykład jako:

float result = Math.Pow(value, 2.0);

To zadziała, ale ma skutek uboczny w postaci zastąpienia prostego mnożenia (value * value) przez wywołanie złożonej funkcji.

Jakie to proste i oczywiste. Czytając jednak komentarze okazuje się, że większość osób, które poszukiwały odpowiedzi, ma na ten temat odmienne zdanie.
Bardzo ciekawa wydała mi się koncepcja zlikwidowania operatora mnożenia, zaproponowana przez jednego z komentujących (ponownie w wolnym tłumaczeniu):


Zaraz; co?
Użyjmy takiego samego "argumentu" dla operatora mnożenia:
 
"Niektóre języki programowania udostępniają operator mnożenia, więc działanie może być zapisane jako: 
float result = value*2; 
zamiast wywoływania funkcji [mnożenia]. Nie mamy czegoś takiego w C#. 
Możliwe byłoby dodanie do języka operatora mnożenia, ale w wielu programach taka operacja jest wywoływania niezmiernie rzadko i nie wydaje się być to uzasadnione, kiedy łatwo jest wywołać funkcję Math.Mult(). 
Dodatkowo martwię się nieco o implementację takiego operatora. Większość kompilatorów przetłumaczy powyższy przykład jako:
float result = Math.Mult(value, 2.0); 
To zadziała, ale ma skutek uboczny w postaci zastąpienia prostego dodawania (value + value) przez wywołanie złożonej funkcji." 
Może powinniście usunąć operator * ?
Wniosek : proste operacje są proste. Ale pisząc kod do obliczeń naukowych i mając formułę, gdzie wykładnik jest liczbą typu double zamiast "2", czytanie tej formuły używającej funkcji Math.Pow jest katorgą (i jest podatne na pomyłki). Powinniście raczej zaimplementować operator ** (czy "^" czy jakikolwiek inny), albo też napisać wyraźnie w pomocy online: "nie powinieneś używać C# do pisania jakiegokolwiek kodu do obliczeń naukowych".
I tym miłym akcentem można podsumować to, co i ja sobie pomyślałem o oryginalnym pomyśle nieimplementowania operatora potęgowania.