Type safe physics operations in C++

Czy sens w C++ definiuje jednostki fizyki jako oddzielne typy i definiuje poprawne operacje pomiędzy tymi typami?

Czy jest jakaś zaleta we wprowadzaniu wielu typów i dużego przeciążenia operatorów zamiast używania zwykłych wartości zmiennoprzecinkowych do ich reprezentowania?

Przykład:

class Time{...};
class Length{...};
class Speed{...};
...
Time operator""_s(long double val){...}
Length operator""_m(long double val){...}
...
Speed operator/(const Length&, const Time&){...}

Gdzie Time, Length i Speed może być utworzony tylko jako typ zwracany z różnych operatorów?

Author: Felics, 2013-11-11

9 answers

Czy sens w C++ definiuje jednostki fizyki jako oddzielne typy i definiuje poprawne operacje pomiędzy tymi typami?

Absolutnie. Standardowa biblioteka Chrono robi to już dla punktów czasowych i czasu trwania.

Czy jest jakaś zaleta we wprowadzaniu wielu typów i dużego przeciążenia operatorów zamiast używania zwykłych wartości zmiennoprzecinkowych do ich reprezentowania?

Tak: możesz użyć systemu typów, aby wychwycić błędy, takie jak dodawanie masy na odległość w czasie kompilacji, bez dodawania narzutu runtime.

Jeśli nie masz ochoty na samodzielne definiowanie typów i operatorów, Boost ma do tego bibliotekę jednostek .

 53
Author: Mike Seymour,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-11 16:23:28

Naprawdę polecam boost::units. Robi cały czas kompilacji konwersji, a także daje błąd czasu kompilacji, jeśli próbujesz użyć błędnych wymiarów przykład kodu psuedo:

length l1, l2, l3;
area a1 = l1 * l2; // Compiles
area a2 = l1 * l2 * l3; // Compile time error, an area can't be the product of three lengths.
volume v1 = l1 * l2 * l3; // Compiles
 21
Author: Viktor Sehr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-11 20:50:48

Szedłem tą drogą. Zaletami są wszystkie normalne liczne i dobre zalety bezpieczeństwa typu. Wady jakie napotkałem:

  • będziesz chciał zapisać wartości pośrednie w obliczeniach... takie jak sekundy do kwadratu. Posiadanie tych wartości jest typem jest nieco bez znaczenia (seconds^2 oczywiście nie jest typem jak velocity jest).
  • będziesz chciał wykonywać coraz bardziej skomplikowane obliczenia, które będą wymagały coraz więcej przeciążeń / operator definiuje do / align = "left" /

Na koniec dnia, jest niezwykle czysty do prostych obliczeń i prostych celów. Ale kiedy matematyka staje się skomplikowana, trudno jest, aby system jednostek wpisanych był miły.

 13
Author: David,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-11 16:24:12

Wszyscy wymienili gwarancje bezpieczeństwa typu jako plus. Kolejnym ogromnym plusem jest możliwość abstrakcji pojęcia (długości) z jednostek (miernika).

Więc na przykład, częstym problemem przy radzeniu sobie z jednostkami jest mieszanie SI z metryką. Gdy pojęcia są abstrakcyjne jako klasy, nie jest to już problemem:

Length width = Length::fromMeters(2.0);
Length height = Length::fromFeet(6.5);
Area area = width * height; //Area is computed correctly!
cout << "The total area is " << area.toInches() << " inches squared.";

Użytkownik klasy nie musi wiedzieć, jakich jednostek używa reprezentacja wewnętrzna... przynajmniej tak długo, jak nie ma poważnych zaokrągleń problemy.


Naprawdę żałuję, że więcej bibliotek trygonometrycznych nie robi tego z kątami, ponieważ zawsze muszę sprawdzić, czy oczekują stopni czy radianów...

 10
Author: BlueRaja - Danny Pflughoeft,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-11 21:42:53

Dla tych, którzy szukają potężnej biblioteki jednostek bezpiecznych w czasie kompilacji, ale wahają się przed przeciągnięciem zależności boost, sprawdź units. Biblioteka jest zaimplementowana jako pojedyncza .plik h bez zależności i pochodzi z projektem do budowy testów jednostkowych / dokumentacji. Jest testowany z msvc2013, 2015 i gcc-4.9.2 i powinien działać również z późniejszymi wersjami tych kompilatorów.

Pełna wersja: jestem autorem biblioteki

 4
Author: Nicolas Holthaus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-28 02:18:47

Tak, to ma sens. Nie tylko w fizyce, ale w każdej dyscyplinie. W finansach, np. stopy procentowe są w jednostkach odwrotnych przedziałów czasowych (zazwyczaj ekspresowe w ciągu roku). Pieniądze mają wiele różnych jednostek. Przeliczanie między nimi może odbywać się tylko przy kursie krzyżowym, ma wymiary jednej waluty podzielone przez inną. Wypłata odsetek, wypłata dywidendy, wypłata kapitału itp. zwykle występują z częstotliwością.

Może zapobiec mnożeniu dwóch wartości i kończeniu się nielegalną wartością. Może zapobiec sumowaniu dolarów i euro itp.

 1
Author: Fred Mitchell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-12 23:23:41

Nie mówię, że się mylisz, ale przesadziliśmy z tym projektem, nad którym pracuję i szczerze wątpię, że jego korzyści przewyższają jego kłopoty. Szczególnie jeśli jesteś w zespole, dobre nazewnictwo zmiennych( wystarczy przeliterować cholerne rzeczy), przeglądanie kodu i Testowanie jednostek zapobiegnie wszelkim problemom. Z drugiej strony, jeśli możesz użyć Boost, jednostki mogą być czymś do sprawdzenia (ja nie).

 1
Author: Scott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-14 16:05:12

Aby sprawdzić bezpieczeństwo typu, możesz użyć dedykowanej biblioteki.

Najbardziej przydatne jest boost:: units, działa perfekcyjnie bez zbędnego czasu wykonania, wiele funkcji. Jeśli ta biblioteka teoretycznie rozwiąże twój problem. Z bardziej praktycznego punktu vew interfejs jest tak niewygodny i źle udokumentowany, że możesz mieć problemy. Ponadto czas kompilacji drastycznie wzrasta wraz z liczbą wymiarów, więc wyraźnie sprawdź, czy możesz skompilować w rozsądnym czasie dużą projekt przed użyciem.

Doc: http://www.boost.org/doc/libs/1_56_0/doc/html/boost_units.html

Alternatywą jest użycie unit_lite. Jest mniej funkcji niż biblioteka boost, ale kompilacja jest szybsza, interfejs prostszy i komunikaty o błędach są czytelne. Ta lib wymaga C++11.

Kod: https://github.com/pierreblavy2/unit_lite

Link do doc znajduje się w opisie Githuba (nie wolno mi zamieszczać więcej niż 2 linków tutaj !!!).

 1
Author: zorbaglub,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-15 16:37:06

Na CPPcon 2015 przedstawiłem prezentację tutoriala na temat Boost.Biblioteka jednostek. Jest to potężna biblioteka, z której powinna korzystać każda aplikacja naukowa. Ale jest trudny w użyciu ze względu na słabą dokumentację. Mam nadzieję, że mój tutorial w tym pomoże. Slajdy / kod znajdziesz tutaj:

 1
Author: Robert Ramey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-30 12:25:27