Programing

C ++에서 안전한 물리 연산 입력

lottogame 2020. 12. 30. 07:40
반응형

C ++에서 안전한 물리 연산 입력


물리 단위를 별도의 유형으로 정의하고 해당 유형간에 유효한 연산을 정의하는 것이 C ++에서 감지됩니까?

일반 부동 소수점 값을 사용하여 표현하는 대신 많은 유형과 많은 연산자 오버로딩을 도입하면 이점이 있습니까?

예:

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

Time, LengthSpeed다른 연산자의 반환 유형으로 만 만들 수있는 곳은 어디 입니까?


물리 단위를 별도의 유형으로 정의하고 해당 유형간에 유효한 연산을 정의하는 것이 C ++에서 감지됩니까?

물론. 표준 Chrono 라이브러리는 이미 시점과 기간에 대해이 작업을 수행합니다.

일반 부동 소수점 값을 사용하여 표현하는 대신 많은 유형과 많은 연산자 오버로딩을 도입하면 이점이 있습니까?

예 : 유형 시스템을 사용하여 런타임 오버 헤드를 추가하지 않고 컴파일 타임에 거리에 질량을 추가하는 것과 같은 오류를 포착 할 수 있습니다.

유형과 연산자를 직접 정의하고 싶지 않다면 Boost에는이를위한 Units 라이브러리 가 있습니다.


나는 이것을 위해 boost :: units정말로 추천 할 것 입니다. 모든 변환 컴파일 시간을 수행하며 잘못된 차원의 의사 코드 예제를 사용하려는 경우 컴파일 시간 오류가 발생합니다.

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

나는이 길을 갔다. 장점은 유형 안전성의 일반적이고 많은 장점입니다. 내가 겪은 단점 :

  • 초 제곱과 같은 계산에서 중간 값을 저장하고 싶을 것입니다. 이러한 값을 유형으로 갖는 것은 다소 의미가 없습니다 (seconds ^ 2는 분명히있는 유형이 아닙니다 velocity).
  • 달성하기 위해 점점 더 많은 과부하 / 연산자가 정의해야하는 점점 더 복잡한 계산을 수행하고 싶을 것입니다.

하루가 끝나면 간단한 계산과 간단한 목적을 위해 매우 깨끗합니다. 그러나 수학이 복잡해지면 형식화 된 단위 체계가 잘 작동하도록하기가 어렵습니다.


모든 사람들은 형식 ​​안전 보장을 플러스로 언급했습니다. 또 다른 큰 장점은 단위 (미터)에서 개념 (길이)을 추상화하는 능력입니다.

예를 들어 단위를 다룰 때 일반적인 문제는 SI와 미터법을 혼합하는 것입니다. 개념이 클래스로 추상화되면 더 이상 문제가되지 않습니다.

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.";

클래스의 사용자는 내부 표현이 사용하는 단위를 알 필요가 없습니다. 적어도 심각한 반올림 문제가없는 한.


나는 더 많은 삼각법 라이브러리가 각도를 사용하여이 작업을 수행했으면 좋겠습니다. 왜냐하면 항상 각도 또는 라디안을 예상하는지 찾아야하기 때문입니다.


강력한 컴파일 타임 유형 안전 유닛 라이브러리를 찾고 있지만 부스트 종속성에서 드래그하는 것을 주저하는 사람들을 위해 units를 확인하십시오 . 라이브러리는 종속성이없는 단일 .h 파일로 구현되며 단위 테스트 / 문서화를 빌드하기위한 프로젝트와 함께 제공됩니다. msvc2013, 2015 및 gcc-4.9.2에서 테스트되었으며 해당 컴파일러의 이후 버전에서도 작동합니다.

전체 공개 : 나는 도서관의 저자입니다


예, 말이됩니다. 물리학뿐만 아니라 모든 분야에서. 금융에서 예를 들어 이자율은 역 시간 간격 단위입니다 (일반적으로 연간 표시). 돈에는 다양한 단위가 있습니다. 그들 사이의 변환은 교차 환율로만 수행 될 수 있으며, 한 통화를 다른 통화로 나눈 차원이 있습니다. 이자 지급, 배당금 지급, 원금 지급 등은 일반적으로 자주 발생합니다.

두 값을 곱하여 잘못된 값으로 끝나는 것을 방지 할 수 있습니다. 달러와 유로 등의 합산을 방지 할 수 있습니다.


나는 당신이 그렇게하는 것이 틀렸다고 말하는 것이 아닙니다. 그러나 우리는 제가 작업하고있는 프로젝트에서 너무 과도하게 지나갔고 솔직히 그것의 이점이 그 번거 로움을 능가한다고 생각합니다. 특히 만약 당신이 팀에 있다면 좋은 변수 이름 지정 (그냥 철자 만 써주세요), 코드 검토, 단위 테스트는 문제를 예방할 수 있습니다. 반면에 Boost를 사용할 수 있다면 유닛은 확인해야 할 것입니다.


형식 안전성을 확인하기 위해 전용 라이브러리를 사용할 수 있습니다.

가장 현명하게 사용하는 것은 boost :: units이며, 실행 시간 오버 헤드없이 많은 기능을 사용하여 영구적으로 작동합니다. 이 라이브러리가 이론적으로 문제를 해결한다면. 좀 더 실용적인 관점에서 보면 인터페이스가 너무 어색하고 잘못 문서화되어 문제가있을 수 있습니다. 또한 컴파일 시간은 차원 수에 따라 크게 증가하므로 사용하기 전에 큰 프로젝트를 적절한 시간에 컴파일 할 수 있는지 명확하게 확인하십시오.

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

대안은 unit_lite를 사용하는 것입니다. 부스트 라이브러리보다 기능이 적지 만 컴파일이 더 빠르고 인터페이스가 더 간단하며 오류 메시지를 읽을 수 있습니다. 이 lib에는 C ++ 11이 필요합니다.

코드 : https://github.com/pierreblavy2/unit_lite

문서에 대한 링크는 github 설명에 있습니다 (여기에 2 개 이상의 링크를 게시 할 수 없습니다 !!!).


CPPcon 2015에서 Boost.Units 라이브러리에 대한 튜토리얼 프레젠테이션을했습니다. 모든 과학 응용 프로그램에서 사용해야하는 강력한 라이브러리입니다. 그러나 문서가 좋지 않아 사용하기가 어렵습니다. 제 튜토리얼이 도움이 되었기를 바랍니다. 여기 에서 슬라이드 / 코드를 찾을 수 있습니다 .

참조 URL : https://stackoverflow.com/questions/19910888/type-safe-physics-operations-in-c

반응형