diff --git a/docs/users_guide/examples/avg_speed.md b/docs/users_guide/examples/avg_speed.md new file mode 100644 index 00000000..1fc1c401 --- /dev/null +++ b/docs/users_guide/examples/avg_speed.md @@ -0,0 +1,134 @@ +--- +tags: + - CGS System + - International System + - Text Formatting +--- + +# `avg_speed` + +!!! example "[Try it on Compiler Explorer](https://godbolt.org/z/75zWdffj1)" + +Let's continue the previous example. This time, our purpose will not be to showcase as many +library features as possible, but we will scope on different interfaces one can provide +with the **mp-units**. We will also describe some advantages and disadvantages of presented +solutions. + +First, we include all the necessary header files and import all the identifiers from the +`mp_units` namespace: + +```cpp title="avg_speed.cpp" linenums="1" +--8<-- "example/avg_speed.cpp:28:38" +``` + +Next, we define two functions calculating average speed based on quantities of fixed units +and integral and floating-point representation types, respectively, and a third function +that we introduced in the [previous example](hello_units.md): + +```cpp title="avg_speed.cpp" linenums="12" +--8<-- "example/avg_speed.cpp:40:54" +``` + +We also added a simple utility to print our results: + +```cpp title="avg_speed.cpp" linenums="27" +--8<-- "example/avg_speed.cpp:56:62" +``` + +Now, let's analyze how those three utility functions behave with different sets of arguments. +First, we are going to use quantities of SI units and integral representation: + +```cpp title="avg_speed.cpp" linenums="27" +--8<-- "example/avg_speed.cpp:64:78" +``` + +The above provides the following output: + +```text +SI units with 'int' as representation +Average speed of a car that makes 220 km in 2 h is 108 km/h. +Average speed of a car that makes 220 km in 2 h is 110 km/h. +Average speed of a car that makes 220 km in 2 h is 110 km/h. +``` + +Please note that in the first two cases, we must convert length from `km` to `m` and +time from `h` to `s`. The converted values are used to calculate speed in `m / s` which +is then again converted to the one in `km / h`. Those conversions not only impact the +application's runtime performance but may also affect the final result. Such truncation +can be easily observed in the first case where we deal with integral representation types +(the resulting speed is `108 km / h`). + +The second scenario is really similar to the previous one, but this time, function arguments +have floating-point representation types: + +```cpp title="avg_speed.cpp" linenums="42" +--8<-- "example/avg_speed.cpp:80:91" +``` + +Conversion from floating-point to integral representation types is +[considered value-truncating](../framework_basics/value_conversions.md#value-truncating-conversions) +and that is why now, in the first case, we need an explicit call to `value_cast`. + +In the text output, we can observe that, again, the resulting value gets truncated during conversions +in the first cast: + +```text +SI units with 'double' as representation +Average speed of a car that makes 220 km in 2 h is 108 km/h. +Average speed of a car that makes 220 km in 2 h is 110 km/h. +Average speed of a car that makes 220 km in 2 h is 110 km/h. +``` + +Next, let's do the same for integral and floating-point representations, but this time +using US Customary units: + +```cpp title="avg_speed.cpp" linenums="54" +--8<-- "example/avg_speed.cpp:93:125" +``` + +One important difference here is the fact that as it is not possible to make a lossless conversion +of miles to meters on a quantity using an integral representation type, so this time, we need a +`value_cast` to force it. + +If we check the text output of the above, we will see the following: + +```text +US Customary Units with 'int' as representation +Average speed of a car that makes 140 mi in 2 h is 111 km/h. +Average speed of a car that makes 140 mi in 2 h is 112.654 km/h. +Average speed of a car that makes 140 mi in 2 h is 112 km/h. + +US Customary Units with 'double' as representation +Average speed of a car that makes 140 mi in 2 h is 111 km/h. +Average speed of a car that makes 140 mi in 2 h is 112.654 km/h. +Average speed of a car that makes 140 mi in 2 h is 112.654 km/h. +``` + +Please note how the first and third results get truncated using integral representation types. + +In the end, we repeat the scenario for CGS units: + +```cpp title="avg_speed.cpp" linenums="87" +--8<-- "example/avg_speed.cpp:127:157" +``` + +Again, we observe `value_cast` being used in the same places and consistent truncation errors +in the text output: + +```text +CGS units with 'int' as representation +Average speed of a car that makes 22000000 cm in 7200 s is 108 km/h. +Average speed of a car that makes 22000000 cm in 7200 s is 110 km/h. +Average speed of a car that makes 22000000 cm in 7200 s is 109 km/h. + +CGS units with 'double' as representation +Average speed of a car that makes 2.2e+07 cm in 7200 s is 108 km/h. +Average speed of a car that makes 2.2e+07 cm in 7200 s is 110 km/h. +Average speed of a car that makes 2.2e+07 cm in 7200 s is 110 km/h. +``` + +The example file ends with a simple `main()` function: + +```cpp title="avg_speed.cpp" linenums="118" +--8<-- "example/avg_speed.cpp:159:" +``` diff --git a/docs/users_guide/examples/hello_units.md b/docs/users_guide/examples/hello_units.md index d40d3b62..6351736d 100644 --- a/docs/users_guide/examples/hello_units.md +++ b/docs/users_guide/examples/hello_units.md @@ -1,19 +1,15 @@ --- tags: - International System - - Text formatting + - Text Formatting --- # `hello_units` -!!! example "[Try it on Compiler Explorer](https://godbolt.org/z/5s9KMYh6d)" +!!! example "[Try it on Compiler Explorer](https://godbolt.org/z/E4rvPGa3n)" This is a really simple example showcasing the features of the **mp-units** library. -```cpp title="hello_units.cpp" linenums="1" ---8<-- "example/hello_units.cpp:28:33" -``` - First, we include the headers for: - a system of quantities (ISQ) @@ -21,22 +17,29 @@ First, we include the headers for: - symbols of international units - text and stream output support +```cpp title="hello_units.cpp" linenums="1" +--8<-- "example/hello_units.cpp:28:33" +``` + +Also, to shorten the definitions, we "import" `mp_units` namespace. + ```cpp title="hello_units.cpp" linenums="7" --8<-- "example/hello_units.cpp:35:36" ``` -Next, to shorten the definitions, we "import" `mp_units` namespace. +Next we define a simple function that calculates average speed based on the provided +arguments of length and time: ```cpp title="hello_units.cpp" linenums="8" --8<-- "example/hello_units.cpp:37:40" ``` The above function template takes any quantities implicitly convertible to `isq::length` -and `isq::time`. Those quantities can use any compatible unit and a representation type. -The function returns a result of a really simple equation and ensures that its quantity -type is implicitly convertible to `isq::speed`. +and `isq::time` respectively. Those quantities can use any compatible unit and a +representation type. The function returns a result of a really simple equation and ensures +that its quantity type is implicitly convertible to `isq::speed`. -!!! note +!!! tip Besides verifying the type returned from the function, constraining a generic return type is really useful for users of such a function as it provides more information @@ -59,24 +62,26 @@ implicitly while including a header file. with a matching kind. - Line `18` calls our function template with quantities of kind `isq::length` and `isq::time` and number and units provided. -- Line `19` explicitly specifies quantity specifications of the quantities passed - to a function template. This time those will not be quantity kinds anymore and will - have more restrictive conversion rules. -- Line `20` changes the unit of a quantity `v3` to `m / s` in a value-preserving way +- Line `19` explicitly provides quantity types of the quantities passed to a function template. + This time those will not be quantity kinds anymore and will have + [more restrictive conversion rules](../framework_basics/simple_and_typed_quantities.md#quantity_cast-to-force-unsafe-conversions). +- Line `20` changes the unit of a quantity `v3` to `m / s` in a + [value-preserving way](../framework_basics/value_conversions.md#value-preserving-conversions) (floating-point representations are considered to be value-preserving). -- Line `21` does a similar operation but this time it would succeed also for non-truncating - cases (if it was the case). -- Line `22` does a value-truncating operation of changing the underlying representation - type from `double` to `int`. +- Line `21` does a similar operation but this time it would succeed also for + [value-truncating cases](../framework_basics/value_conversions.md#value-truncating-conversions) + (if it was the case). +- Line `22` does a [value-truncating conversion](../framework_basics/value_conversions.md#value-truncating-conversions) + of changing the underlying representation type from `double` to `int`. ```cpp title="hello_units.cpp" linenums="23" --8<-- "example/hello_units.cpp:55" ``` -The above presents various ways to print a quantity. Both stream insertion operations -and `std::format` are supported. +The above presents [various ways to print a quantity](../framework_basics/text_output.md). +Both stream insertion operations and `std::format` are supported. -!!! note +!!! tip `MP_UNITS_STD_FMT` is used for compatibility reasons. In case a specific compiler does not support `std::format` or a user prefers to use `{fmt}` library, this macro diff --git a/docs/users_guide/examples/si_constants.md b/docs/users_guide/examples/si_constants.md new file mode 100644 index 00000000..192843dc --- /dev/null +++ b/docs/users_guide/examples/si_constants.md @@ -0,0 +1,44 @@ +--- +tags: + - Physical Constants + - Text Formatting +--- + +# `si_constants` + +!!! example "[Try it on Compiler Explorer](https://godbolt.org/z/????)" + +The next example presents all the seven defining constants of the SI system. We can observe +how [Faster-than-lightspeed Constants](../framework_basics/faster_than_lightspeed_constants.md) +work in practice. + +```cpp title="si_constants.cpp" linenums="1" +--8<-- "example/si_constants.cpp:28:34" +``` + +As always, we start with the inclusion of all the needed header files. After that, for +the simplicity of this example, we +[hack the character of quantities](../framework_basics/character_of_a_quantity.md#hacking-the-character) +to be able to express vector quantities with simple scalar types. + +```cpp title="si_constants.cpp" linenums="1" +--8<-- "example/si_constants.cpp:36:" +``` + +The main part of the example prints all of the SI-defining constants. While analyzing the output of +this program (provided below), we can easily notice that a direct printing of the quantity provides +just a value `1` with a proper constant symbol. This is the main power of the +[Faster-than-lightspeed Constants](../framework_basics/faster_than_lightspeed_constants.md) feature. +Only after we explicitly convert the unit of a quantity to proper SI units we get an actual numeric +value of the constant. + +```text +The seven defining constants of the SI and the seven corresponding units they define: +- hyperfine transition frequency of Cs: 1 Δν_Cs = 9192631770 Hz +- speed of light in vacuum: 1 c = 299792458 m/s +- Planck constant: 1 h = 6.62607015e-34 J s +- elementary charge: 1 e = 1.602176634e-19 C +- Boltzmann constant: 1 k = 1.380649e-23 J/K +- Avogadro constant: 1 N_A = 6.02214076e+23 1/mol +- luminous efficacy: 1 K_cd = 683 lm/W +``` diff --git a/mkdocs.yml b/mkdocs.yml index 4ddfeb5a..43ee4c49 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -140,6 +140,8 @@ nav: - Examples: - Tags Index: users_guide/examples/tags_index.md - hello_units: users_guide/examples/hello_units.md + - avg_speed: users_guide/examples/avg_speed.md + - si_constants: users_guide/examples/si_constants.md - Library Reference: - Core Library: library_reference/core_library.md - Magnitudes: library_reference/magnitudes.md