Files
mp-units/head/users_guide/framework_basics/quantity_arithmetics/index.html
T

2673 lines
92 KiB
HTML

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="The quantities and units library for C++">
<meta name="author" content="mp-units Team">
<link rel="canonical" href="https://mpusz.github.io/mp-units/head/users_guide/framework_basics/quantity_arithmetics/">
<link rel="prev" href="../dimensionless_quantities/">
<link rel="next" href="../generic_interfaces/">
<link rel="alternate" type="application/rss+xml" title="RSS feed" href="../../../feed_rss_created.xml">
<link rel="alternate" type="application/rss+xml" title="RSS feed of updated content" href="../../../feed_rss_updated.xml">
<link rel="icon" href="../../../assets/images/mp-units-color.svg">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.5.42">
<title>Quantity Arithmetics - mp-units</title>
<link rel="stylesheet" href="../../../assets/stylesheets/main.0253249f.min.css">
<link rel="stylesheet" href="../../../assets/stylesheets/palette.06af60db.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<link rel="stylesheet" href="../../../stylesheets/extra.css">
<script>__md_scope=new URL("../../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
<meta property="og:type" content="website" >
<meta property="og:title" content="Quantity Arithmetics - mp-units" >
<meta property="og:description" content="The quantities and units library for C++" >
<meta property="og:image" content="https://mpusz.github.io/mp-units/head/assets/images/social/users_guide/framework_basics/quantity_arithmetics.png" >
<meta property="og:image:type" content="image/png" >
<meta property="og:image:width" content="1200" >
<meta property="og:image:height" content="630" >
<meta property="og:url" content="https://mpusz.github.io/mp-units/head/users_guide/framework_basics/quantity_arithmetics/" >
<meta name="twitter:card" content="summary_large_image" >
<meta name="twitter:title" content="Quantity Arithmetics - mp-units" >
<meta name="twitter:description" content="The quantities and units library for C++" >
<meta name="twitter:image" content="https://mpusz.github.io/mp-units/head/assets/images/social/users_guide/framework_basics/quantity_arithmetics.png" >
</head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#quantity-arithmetics" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<div data-md-color-scheme="default" data-md-component="outdated" hidden>
<aside class="md-banner md-banner--warning">
<div class="md-banner__inner md-grid md-typeset">
You're not viewing the latest version.
<a href="../../../..">
<strong>Click here to go to latest.</strong>
</a>
</div>
<script>var el=document.querySelector("[data-md-component=outdated]"),outdated=__md_get("__outdated",sessionStorage);!0===outdated&&el&&(el.hidden=!1)</script>
</aside>
</div>
<header class="md-header" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="../../.." title="mp-units" class="md-header__button md-logo" aria-label="mp-units" data-md-component="logo">
<img src="../../../assets/images/mp-units-transparent-white.svg" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
mp-units
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Quantity Arithmetics
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="(prefers-color-scheme)" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_0">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7a5 5 0 0 0-5 5 5 5 0 0 0 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1M8 13h8v-2H8zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4a5 5 0 0 0 5-5 5 5 0 0 0-5-5"/></svg>
</label>
<input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="custom" data-md-color-accent="custom" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_2" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 7a5 5 0 0 1 5 5 5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0-7 2.39 3.42C13.65 5.15 12.84 5 12 5s-1.65.15-2.39.42zM3.34 7l4.16-.35A7.2 7.2 0 0 0 5.94 8.5c-.44.74-.69 1.5-.83 2.29zm.02 10 1.76-3.77a7.131 7.131 0 0 0 2.38 4.14zM20.65 7l-1.77 3.79a7.02 7.02 0 0 0-2.38-4.15zm-.01 10-4.14.36c.59-.51 1.12-1.14 1.54-1.86.42-.73.69-1.5.83-2.29zM12 22l-2.41-3.44c.74.27 1.55.44 2.41.44.82 0 1.63-.17 2.37-.44z"/></svg>
</label>
<input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="black" data-md-color-accent="custom" aria-label="Switch to system preference" type="radio" name="__palette" id="__palette_2">
<label class="md-header__button md-icon" title="Switch to system preference" for="__palette_0" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m17.75 4.09-2.53 1.94.91 3.06-2.63-1.81-2.63 1.81.91-3.06-2.53-1.94L12.44 4l1.06-3 1.06 3zm3.5 6.91-1.64 1.25.59 1.98-1.7-1.17-1.7 1.17.59-1.98L15.75 11l2.06-.05L18.5 9l.69 1.95zm-2.28 4.95c.83-.08 1.72 1.1 1.19 1.85-.32.45-.66.87-1.08 1.27C15.17 23 8.84 23 4.94 19.07c-3.91-3.9-3.91-10.24 0-14.14.4-.4.82-.76 1.27-1.08.75-.53 1.93.36 1.85 1.19-.27 2.86.69 5.83 2.89 8.02a9.96 9.96 0 0 0 8.02 2.89m-1.64 2.02a12.08 12.08 0 0 1-7.8-3.47c-2.17-2.19-3.33-5-3.49-7.82-2.81 3.14-2.7 7.96.31 10.98 3.02 3.01 7.84 3.12 10.98.31"/></svg>
</label>
</form>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<a href="javascript:void(0)" class="md-search__icon md-icon" title="Share" aria-label="Share" data-clipboard data-clipboard-text="" data-md-component="search-share" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"/></svg>
</a>
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
<div class="md-search__suggest" data-md-component="search-suggest"></div>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/mpusz/mp-units" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81"/></svg>
</div>
<div class="md-source__repository">
mpusz/mp-units
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
<div class="md-grid">
<ul class="md-tabs__list">
<li class="md-tabs__item">
<a href="../../.." class="md-tabs__link">
Home
</a>
</li>
<li class="md-tabs__item">
<a href="../../../getting_started/introduction/" class="md-tabs__link">
Getting Started
</a>
</li>
<li class="md-tabs__item md-tabs__item--active">
<a href="../../terms_and_definitions/" class="md-tabs__link">
User's Guide
</a>
</li>
<li class="md-tabs__item">
<a href="../../../api_reference/" class="md-tabs__link">
API Reference
</a>
</li>
<li class="md-tabs__item">
<a href="../../../blog/" class="md-tabs__link">
Blog
</a>
</li>
<li class="md-tabs__item">
<a href="../../../release_notes/" class="md-tabs__link">
Release Notes
</a>
</li>
</ul>
</div>
</nav>
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary md-nav--lifted md-nav--integrated" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../../.." title="mp-units" class="md-nav__button md-logo" aria-label="mp-units" data-md-component="logo">
<img src="../../../assets/images/mp-units-transparent-white.svg" alt="logo">
</a>
mp-units
</label>
<div class="md-nav__source">
<a href="https://github.com/mpusz/mp-units" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81"/></svg>
</div>
<div class="md-source__repository">
mpusz/mp-units
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../.." class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2" >
<label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0">
<span class="md-ellipsis">
Getting Started
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2">
<span class="md-nav__icon md-icon"></span>
Getting Started
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../../getting_started/introduction/" class="md-nav__link">
<span class="md-ellipsis">
Introduction
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../getting_started/quick_start/" class="md-nav__link">
<span class="md-ellipsis">
Quick Start
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../getting_started/look_and_feel/" class="md-nav__link">
<span class="md-ellipsis">
Look and Feel
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../getting_started/project_structure/" class="md-nav__link">
<span class="md-ellipsis">
Project Structure
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../getting_started/cpp_compiler_support/" class="md-nav__link">
<span class="md-ellipsis">
C++ compiler support (API/ABI)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../getting_started/installation_and_usage/" class="md-nav__link">
<span class="md-ellipsis">
Installation and Usage
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../getting_started/contributing/" class="md-nav__link">
<span class="md-ellipsis">
Contributing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../getting_started/faq/" class="md-nav__link">
<span class="md-ellipsis">
FAQ
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" checked>
<label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="">
<span class="md-ellipsis">
User's Guide
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_3">
<span class="md-nav__icon md-icon"></span>
User's Guide
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../terms_and_definitions/" class="md-nav__link">
<span class="md-ellipsis">
Terms and Definitions
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_2" checked>
<label class="md-nav__link" for="__nav_3_2" id="__nav_3_2_label" tabindex="0">
<span class="md-ellipsis">
Framework Basics
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_3_2_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_3_2">
<span class="md-nav__icon md-icon"></span>
Framework Basics
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../interface_introduction/" class="md-nav__link">
<span class="md-ellipsis">
Interface Introduction
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../design_overview/" class="md-nav__link">
<span class="md-ellipsis">
Design Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../systems_of_quantities/" class="md-nav__link">
<span class="md-ellipsis">
Systems of Quantities
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../systems_of_units/" class="md-nav__link">
<span class="md-ellipsis">
Systems of Units
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../simple_and_typed_quantities/" class="md-nav__link">
<span class="md-ellipsis">
Simple and Typed Quantities
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../value_conversions/" class="md-nav__link">
<span class="md-ellipsis">
Value Conversions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../character_of_a_quantity/" class="md-nav__link">
<span class="md-ellipsis">
Character of a Quantity
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../dimensionless_quantities/" class="md-nav__link">
<span class="md-ellipsis">
Dimensionless Quantities
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Quantity Arithmetics
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Quantity Arithmetics
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#quantity-is-a-numeric-wrapper" class="md-nav__link">
<span class="md-ellipsis">
quantity is a numeric wrapper
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#addition-and-subtraction" class="md-nav__link">
<span class="md-ellipsis">
Addition and subtraction
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#multiplication-and-division" class="md-nav__link">
<span class="md-ellipsis">
Multiplication and division
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#modulo" class="md-nav__link">
<span class="md-ellipsis">
Modulo
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#comparison-against-zero" class="md-nav__link">
<span class="md-ellipsis">
Comparison against zero
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#other-maths" class="md-nav__link">
<span class="md-ellipsis">
Other maths
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../generic_interfaces/" class="md-nav__link">
<span class="md-ellipsis">
Generic Interfaces
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../faster_than_lightspeed_constants/" class="md-nav__link">
<span class="md-ellipsis">
Faster-than-lightspeed Constants
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../the_affine_space/" class="md-nav__link">
<span class="md-ellipsis">
The Affine Space
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../obtaining_metadata/" class="md-nav__link">
<span class="md-ellipsis">
Obtaining Metadata
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../concepts/" class="md-nav__link">
<span class="md-ellipsis">
Concepts
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../text_output/" class="md-nav__link">
<span class="md-ellipsis">
Text Output
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_3" >
<label class="md-nav__link" for="__nav_3_3" id="__nav_3_3_label" tabindex="0">
<span class="md-ellipsis">
Systems
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_3_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3_3">
<span class="md-nav__icon md-icon"></span>
Systems
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../systems/introduction/" class="md-nav__link">
<span class="md-ellipsis">
Introduction
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../systems/isq/" class="md-nav__link">
<span class="md-ellipsis">
International System of Quantities (ISQ)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../systems/si/" class="md-nav__link">
<span class="md-ellipsis">
International System of Units (SI)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../systems/strong_angular_system/" class="md-nav__link">
<span class="md-ellipsis">
Strong Angular System
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../systems/natural_units/" class="md-nav__link">
<span class="md-ellipsis">
Natural Units
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_4" >
<label class="md-nav__link" for="__nav_3_4" id="__nav_3_4_label" tabindex="0">
<span class="md-ellipsis">
Use Cases
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_3_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3_4">
<span class="md-nav__icon md-icon"></span>
Use Cases
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../use_cases/pure_dimensional_analysis/" class="md-nav__link">
<span class="md-ellipsis">
Pure Dimensional Analysis
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../use_cases/working_with_legacy_interfaces/" class="md-nav__link">
<span class="md-ellipsis">
Working with Legacy Interfaces
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../use_cases/using_custom_representation_types/" class="md-nav__link">
<span class="md-ellipsis">
Using Custom Representation Types
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../use_cases/interoperability_with_other_libraries/" class="md-nav__link">
<span class="md-ellipsis">
Interoperability with Other Libraries
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../use_cases/extending_the_library/" class="md-nav__link">
<span class="md-ellipsis">
Extending the Library
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../use_cases/wide_compatibility/" class="md-nav__link">
<span class="md-ellipsis">
Wide Compatibility
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_5" >
<label class="md-nav__link" for="__nav_3_5" id="__nav_3_5_label" tabindex="0">
<span class="md-ellipsis">
Examples
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_3_5_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3_5">
<span class="md-nav__icon md-icon"></span>
Examples
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../examples/tags_index/" class="md-nav__link">
<span class="md-ellipsis">
Tags Index
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_5_2" >
<label class="md-nav__link" for="__nav_3_5_2" id="__nav_3_5_2_label" tabindex="0">
<span class="md-ellipsis">
All Examples
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="3" aria-labelledby="__nav_3_5_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3_5_2">
<span class="md-nav__icon md-icon"></span>
All Examples
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../examples/hello_units/" class="md-nav__link">
<span class="md-ellipsis">
hello_units
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../examples/avg_speed/" class="md-nav__link">
<span class="md-ellipsis">
avg_speed
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../examples/si_constants/" class="md-nav__link">
<span class="md-ellipsis">
si_constants
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../examples/hw_voltage/" class="md-nav__link">
<span class="md-ellipsis">
hw_voltage
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_6" >
<label class="md-nav__link" for="__nav_3_6" id="__nav_3_6_label" tabindex="0">
<span class="md-ellipsis">
Appendix
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_3_6_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3_6">
<span class="md-nav__icon md-icon"></span>
Appendix
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../../appendix/glossary/" class="md-nav__link">
<span class="md-ellipsis">
Glossary
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../appendix/references/" class="md-nav__link">
<span class="md-ellipsis">
References
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../../../api_reference/" class="md-nav__link">
<span class="md-ellipsis">
API Reference
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" >
<div class="md-nav__link md-nav__container">
<a href="../../../blog/" class="md-nav__link ">
<span class="md-ellipsis">
Blog
</span>
</a>
<label class="md-nav__link " for="__nav_5" id="__nav_5_label" tabindex="0">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5">
<span class="md-nav__icon md-icon"></span>
Blog
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_2" >
<label class="md-nav__link" for="__nav_5_2" id="__nav_5_2_label" tabindex="0">
<span class="md-ellipsis">
Archive
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_2">
<span class="md-nav__icon md-icon"></span>
Archive
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../../blog/archive/2024/" class="md-nav__link">
<span class="md-ellipsis">
2024
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../blog/archive/2023/" class="md-nav__link">
<span class="md-ellipsis">
2023
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_3" >
<label class="md-nav__link" for="__nav_5_3" id="__nav_5_3_label" tabindex="0">
<span class="md-ellipsis">
Categories
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_3">
<span class="md-nav__icon md-icon"></span>
Categories
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../../blog/category/metrology/" class="md-nav__link">
<span class="md-ellipsis">
Metrology
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../blog/category/releases/" class="md-nav__link">
<span class="md-ellipsis">
Releases
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../blog/category/wg21-updates/" class="md-nav__link">
<span class="md-ellipsis">
WG21 Updates
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../../../release_notes/" class="md-nav__link">
<span class="md-ellipsis">
Release Notes
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<a href="https://github.com/mpusz/mp-units/edit/master/docs/users_guide/framework_basics/quantity_arithmetics.md" title="Edit this page" class="md-content__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 20H6V4h7v5h5v3.1l2-2V8l-6-6H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h4zm10.2-7c.1 0 .3.1.4.2l1.3 1.3c.2.2.2.6 0 .8l-1 1-2.1-2.1 1-1c.1-.1.2-.2.4-.2m0 3.9L14.1 23H12v-2.1l6.1-6.1z"/></svg>
</a>
<a href="https://github.com/mpusz/mp-units/raw/master/docs/users_guide/framework_basics/quantity_arithmetics.md" title="View source of this page" class="md-content__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 18c.56 0 1 .44 1 1s-.44 1-1 1-1-.44-1-1 .44-1 1-1m0-3c-2.73 0-5.06 1.66-6 4 .94 2.34 3.27 4 6 4s5.06-1.66 6-4c-.94-2.34-3.27-4-6-4m0 6.5a2.5 2.5 0 0 1-2.5-2.5 2.5 2.5 0 0 1 2.5-2.5 2.5 2.5 0 0 1 2.5 2.5 2.5 2.5 0 0 1-2.5 2.5M9.27 20H6V4h7v5h5v4.07c.7.08 1.36.25 2 .49V8l-6-6H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h4.5a8.2 8.2 0 0 1-1.23-2"/></svg>
</a>
<h1 id="quantity-arithmetics">Quantity Arithmetics<a class="headerlink" href="#quantity-arithmetics" title="Permanent link">&para;</a></h1>
<h2 id="quantity-is-a-numeric-wrapper"><code>quantity</code> is a numeric wrapper<a class="headerlink" href="#quantity-is-a-numeric-wrapper" title="Permanent link">&para;</a></h2>
<p>If we think about it, the <code>quantity</code> class template is just a "smart" numeric wrapper. It exposes
properly constrained set of arithmetic operations on one or two operands.</p>
<div class="admonition important">
<p class="admonition-title">Important: <code>quantity</code> propagates the underlying interface</p>
<p>Every single arithmetic operator is exposed by the <code>quantity</code> class template only if
the underlying representation type provides it as well, and when its implementation has proper
semantics (e.g., returns a reasonable type).</p>
</div>
<p>For example, in the following code, <code>-a</code> will compile only if <code>MyInt</code> exposes such an operation
as well:</p>
<div class="language-cpp highlight"><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="n">quantity</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">MyInt</span><span class="p">{</span><span class="mi">42</span><span class="p">}</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">;</span>
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a><span class="n">quantity</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">a</span><span class="p">;</span>
</span></code></pre></div>
<p>Assuming that:</p>
<ul>
<li><code>q</code> is our quantity,</li>
<li><code>qi</code> is a quantity implicitly convertible to <code>q</code>,</li>
<li><code>qk</code> is a <a href="../systems_of_quantities/#quantities-of-the-same-kind">quantity of the same kind</a> as <code>q</code>,</li>
<li><code>q1</code> is a <a href="../dimensionless_quantities/">quantity of <code>dimension_one</code> with the unit <code>one</code></a>,</li>
<li><code>qq</code> is any other quantity,</li>
<li><code>number</code> is a value of a type "compatible" with <code>q</code>'s representation type,</li>
</ul>
<p>here is the list of all the supported operators:</p>
<ul>
<li>unary:<ul>
<li><code>+q</code></li>
<li><code>-q</code></li>
<li><code>++q</code></li>
<li><code>q++</code></li>
<li><code>--q</code></li>
<li><code>q--</code></li>
</ul>
</li>
<li>compound assignment:<ul>
<li><code>q += qi</code></li>
<li><code>q -= qi</code></li>
<li><code>q %= qi</code></li>
<li><code>q *= number</code></li>
<li><code>q *= q1</code></li>
<li><code>q /= number</code></li>
<li><code>q /= q1</code></li>
</ul>
</li>
<li>binary:<ul>
<li><code>q + qk</code></li>
<li><code>q - qk</code></li>
<li><code>q % qk</code></li>
<li><code>q * qq</code></li>
<li><code>q * number</code></li>
<li><code>number * q</code></li>
<li><code>q / qq</code></li>
<li><code>q / number</code></li>
<li><code>number / q</code></li>
</ul>
</li>
<li>ordering and comparison:<ul>
<li><code>q == qk</code></li>
<li><code>q &lt;=&gt; qk</code></li>
</ul>
</li>
</ul>
<p>As we can see, there are plenty of operations one can do on a value of a <code>quantity</code> type. As most
of them are obvious, in the following chapters, we will discuss only the most important or non-trivial
aspects of quantity arithmetics.</p>
<h2 id="addition-and-subtraction">Addition and subtraction<a class="headerlink" href="#addition-and-subtraction" title="Permanent link">&para;</a></h2>
<p>Quantities can easily be added or subtracted from each other:</p>
<div class="language-cpp highlight"><pre><span></span><code><span id="__span-1-1"><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="k">static_assert</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">);</span>
</span><span id="__span-1-2"><a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a><span class="k">static_assert</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">);</span>
</span><span id="__span-1-3"><a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a><span class="k">static_assert</span><span class="p">(</span><span class="n">isq</span><span class="o">::</span><span class="n">height</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">isq</span><span class="o">::</span><span class="n">height</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">isq</span><span class="o">::</span><span class="n">height</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">));</span>
</span><span id="__span-1-4"><a id="__codelineno-1-4" name="__codelineno-1-4" href="#__codelineno-1-4"></a><span class="k">static_assert</span><span class="p">(</span><span class="n">isq</span><span class="o">::</span><span class="n">height</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">isq</span><span class="o">::</span><span class="n">height</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">isq</span><span class="o">::</span><span class="n">height</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">));</span>
</span></code></pre></div>
<p>The above uses the same types for LHS, RHS, and the result, but in general, we can add, subtract,
or compare the values of any quantity type as long as both
<a href="../systems_of_quantities/#quantities-of-the-same-kind">quantities are of the same kind</a>.
The result of such an operation will be the common type of the arguments:</p>
<div class="language-cpp highlight"><pre><span></span><code><span id="__span-2-1"><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a><span class="k">static_assert</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">km</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1.5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mf">1001.5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">);</span>
</span><span id="__span-2-2"><a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a><span class="k">static_assert</span><span class="p">(</span><span class="n">isq</span><span class="o">::</span><span class="n">height</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">isq</span><span class="o">::</span><span class="n">width</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">isq</span><span class="o">::</span><span class="n">length</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">));</span>
</span><span id="__span-2-3"><a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a><span class="k">static_assert</span><span class="p">(</span><span class="n">isq</span><span class="o">::</span><span class="n">height</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">isq</span><span class="o">::</span><span class="n">distance</span><span class="p">(</span><span class="mf">0.5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mf">1.5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">);</span>
</span><span id="__span-2-4"><a id="__codelineno-2-4" name="__codelineno-2-4" href="#__codelineno-2-4"></a><span class="k">static_assert</span><span class="p">(</span><span class="n">isq</span><span class="o">::</span><span class="n">radius</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mf">0.5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">isq</span><span class="o">::</span><span class="n">radius</span><span class="p">(</span><span class="mf">0.5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">));</span>
</span></code></pre></div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Please note that for the compound assignment operators, we always need to end up with the
left-hand-side argument type:</p>
<div class="language-cpp highlight"><pre><span></span><code><span id="__span-3-1"><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a><span class="k">static_assert</span><span class="p">((</span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">km</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">1001</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">);</span>
</span><span id="__span-3-2"><a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a><span class="k">static_assert</span><span class="p">((</span><span class="n">isq</span><span class="o">::</span><span class="n">length</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">)</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">isq</span><span class="o">::</span><span class="n">height</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">))</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">isq</span><span class="o">::</span><span class="n">length</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">));</span>
</span><span id="__span-3-3"><a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a><span class="k">static_assert</span><span class="p">((</span><span class="n">isq</span><span class="o">::</span><span class="n">height</span><span class="p">(</span><span class="mf">1.5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">)</span><span class="w"> </span><span class="o">-=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">isq</span><span class="o">::</span><span class="n">height</span><span class="p">(</span><span class="mf">0.5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">));</span>
</span></code></pre></div>
<p>If we will break typical library's convertibility rules, the following code will not compile:</p>
<div class="language-cpp highlight"><pre><span></span><code><span id="__span-4-1"><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="n">quantity</span><span class="w"> </span><span class="n">q1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">-=</span><span class="w"> </span><span class="mf">0.5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">;</span><span class="w"> </span><span class="c1">// Compile-time error(1)</span>
</span><span id="__span-4-2"><a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a><span class="n">quantity</span><span class="w"> </span><span class="n">q2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">km</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">;</span><span class="w"> </span><span class="c1">// Compile-time error(2)</span>
</span><span id="__span-4-3"><a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a><span class="n">quantity</span><span class="w"> </span><span class="n">q3</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">isq</span><span class="o">::</span><span class="n">height</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">)</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">isq</span><span class="o">::</span><span class="n">length</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">);</span><span class="w"> </span><span class="c1">// Compile-time error(3)</span>
</span></code></pre></div>
<ol>
<li>Conversion of the floating-point to integral representation type is
<a href="../value_conversions/">considered narrowing</a>.</li>
<li>Conversion of quantity with integral representation type from a unit of a higher resolution
to the one with a lower resolution is <a href="../value_conversions/">considered narrowing</a>.</li>
<li>Conversion from a more generic quantity type to a more specific one is
<a href="../simple_and_typed_quantities/#quantity_cast-to-force-unsafe-conversions">considered unsafe</a>.</li>
</ol>
</div>
<h2 id="multiplication-and-division">Multiplication and division<a class="headerlink" href="#multiplication-and-division" title="Permanent link">&para;</a></h2>
<p>Multiplying or dividing a quantity by a number does not change its quantity type or unit. However,
its representation type may change. For example:</p>
<div class="language-cpp highlight"><pre><span></span><code><span id="__span-5-1"><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a><span class="k">static_assert</span><span class="p">(</span><span class="n">isq</span><span class="o">::</span><span class="n">height</span><span class="p">(</span><span class="mi">3</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">0.5</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">isq</span><span class="o">::</span><span class="n">height</span><span class="p">(</span><span class="mf">1.5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">));</span>
</span></code></pre></div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Unless we use a compound assignment operator, in which case we always have to result with
the type of the left-hand-side argument. This, together with the fact that this library
tries to prevent truncation of a quantity value means, that the following does not compile:</p>
<div class="language-cpp highlight"><pre><span></span><code><span id="__span-6-1"><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a><span class="n">quantity</span><span class="w"> </span><span class="n">q</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">isq</span><span class="o">::</span><span class="n">height</span><span class="p">(</span><span class="mi">3</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">)</span><span class="w"> </span><span class="o">*=</span><span class="w"> </span><span class="mf">0.5</span><span class="p">;</span><span class="w"> </span><span class="c1">// Compile-time error</span>
</span></code></pre></div>
</div>
<p>However, suppose we multiply or divide quantities of the same or different types or we divide a raw
number by a quantity. In that case, we most probably will end up in a quantity of yet another type:</p>
<div class="language-cpp highlight"><pre><span></span><code><span id="__span-7-1"><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a><span class="k">static_assert</span><span class="p">(</span><span class="mi">120</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">km</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">h</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">60</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">km</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">h</span><span class="p">);</span>
</span><span id="__span-7-2"><a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a><span class="k">static_assert</span><span class="p">(</span><span class="n">isq</span><span class="o">::</span><span class="n">width</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">isq</span><span class="o">::</span><span class="n">length</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">isq</span><span class="o">::</span><span class="n">area</span><span class="p">(</span><span class="mi">4</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m2</span><span class="p">));</span>
</span><span id="__span-7-3"><a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a><span class="k">static_assert</span><span class="p">(</span><span class="mi">50</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">isq</span><span class="o">::</span><span class="n">time</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">s</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">isq</span><span class="o">::</span><span class="n">frequency</span><span class="p">(</span><span class="mi">50</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">Hz</span><span class="p">));</span>
</span></code></pre></div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>An exception from the above rule happens when one of the arguments is
a <a href="../dimensionless_quantities/">dimensionless quantity</a>. If we multiply or divide by such
a quantity, the quantity type will not change. If such a quantity has a unit <code>one</code>,
also the unit of a quantity will not change:</p>
<div class="language-cpp highlight"><pre><span></span><code><span id="__span-8-1"><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a><span class="k">static_assert</span><span class="p">(</span><span class="mi">120</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">one</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">60</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">);</span>
</span></code></pre></div>
</div>
<p>An interesting special case happens when we divide the same quantity kinds or multiply a quantity
by its inverted type. In such a case, we end up with a <a href="../dimensionless_quantities/">dimensionless quantity</a>.</p>
<div class="language-cpp highlight"><pre><span></span><code><span id="__span-9-1"><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a><span class="k">static_assert</span><span class="p">(</span><span class="n">isq</span><span class="o">::</span><span class="n">height</span><span class="p">(</span><span class="mi">4</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">isq</span><span class="o">::</span><span class="n">width</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">one</span><span class="p">);</span><span class="w"> </span><span class="c1">// (1)!</span>
</span><span id="__span-9-2"><a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a><span class="k">static_assert</span><span class="p">(</span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="p">(</span><span class="mi">120</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">min</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">one</span><span class="p">);</span><span class="w"> </span><span class="c1">// (2)!</span>
</span><span id="__span-9-3"><a id="__codelineno-9-3" name="__codelineno-9-3" href="#__codelineno-9-3"></a><span class="k">static_assert</span><span class="p">(</span><span class="mf">5.</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="p">(</span><span class="mi">120</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">min</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mf">2.5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">one</span><span class="p">);</span>
</span></code></pre></div>
<ol>
<li>The resulting quantity type of the LHS is <code>isq::height / isq::width</code>, which is a quantity of the
dimensionless kind.</li>
<li>The resulting quantity of the LHS is <code>0 * dimensionless[h / min]</code>. To be consistent with the division
of different quantity types, we do not convert quantity values to a common unit before the division.</li>
</ol>
<div class="admonition important">
<p class="admonition-title">Important: Beware of integral division</p>
<p>The physical units library can't do any runtime branching logic for the division operator.
All logic must be done at compile-time when the actual values are unknown, and the quantity types
can't change at runtime.</p>
<p>If we expect <code>120 * km / (2 * h)</code> to return <code>60 km / h</code>, we have to agree with the fact that
<code>5 * km / (24 * h)</code> returns <code>0 km/h</code>. We can't do a range check at runtime to dynamically adjust scales
and types based on the values of provided function arguments.</p>
<p><strong>This is why we often prefer floating-point representation types when dealing with units.</strong>
Some popular physical units libraries even
<a href="https://aurora-opensource.github.io/au/main/troubleshooting/#integer-division-forbidden">forbid integer division at all</a>.</p>
</div>
<h2 id="modulo">Modulo<a class="headerlink" href="#modulo" title="Permanent link">&para;</a></h2>
<p>Now that we know how addition, subtraction, multiplication, and division work, it is time to discuss
modulo. What would we expect to be returned from the following quantity equation?</p>
<div class="language-cpp highlight"><pre><span></span><code><span id="__span-10-1"><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="k">auto</span><span class="w"> </span><span class="n">q</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="p">(</span><span class="mi">120</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">min</span><span class="p">);</span>
</span></code></pre></div>
<p>Most of us would probably expect to see <code>1 h</code> or <code>60 min</code> as a result. And this is where the problems start.</p>
<p>C++ language defines its <code>/</code> and <code>%</code> operators with the <a href="https://eel.is/c++draft/expr.mul#4">quotient-remainder theorem</a>:</p>
<div class="language-text highlight"><pre><span></span><code><span id="__span-11-1"><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a>q = a / b;
</span><span id="__span-11-2"><a id="__codelineno-11-2" name="__codelineno-11-2" href="#__codelineno-11-2"></a>r = a % b;
</span><span id="__span-11-3"><a id="__codelineno-11-3" name="__codelineno-11-3" href="#__codelineno-11-3"></a>q * b + r == a;
</span></code></pre></div>
<p>The important property of the modulo operation is that it only works for integral representation
types (it is undefined what modulo for floating-point types means). However, as we saw in the previous
chapter, integral types are tricky because they often truncate the value.</p>
<p>From the quotient-remainder theorem, the result of modulo operation is <code>r = a - q * b</code>.
Let's see what we get from such a quantity equation on integral representation types:</p>
<div class="language-cpp highlight"><pre><span></span><code><span id="__span-12-1"><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a><span class="k">const</span><span class="w"> </span><span class="n">quantity</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">h</span><span class="p">;</span>
</span><span id="__span-12-2"><a id="__codelineno-12-2" name="__codelineno-12-2" href="#__codelineno-12-2"></a><span class="k">const</span><span class="w"> </span><span class="n">quantity</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">120</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">min</span><span class="p">;</span>
</span><span id="__span-12-3"><a id="__codelineno-12-3" name="__codelineno-12-3" href="#__codelineno-12-3"></a><span class="k">const</span><span class="w"> </span><span class="n">quantity</span><span class="w"> </span><span class="n">q</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">b</span><span class="p">;</span>
</span><span id="__span-12-4"><a id="__codelineno-12-4" name="__codelineno-12-4" href="#__codelineno-12-4"></a><span class="k">const</span><span class="w"> </span><span class="n">quantity</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">q</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">b</span><span class="p">;</span>
</span><span id="__span-12-5"><a id="__codelineno-12-5" name="__codelineno-12-5" href="#__codelineno-12-5"></a>
</span><span id="__span-12-6"><a id="__codelineno-12-6" name="__codelineno-12-6" href="#__codelineno-12-6"></a><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;reminder: &quot;</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span>
</span></code></pre></div>
<p>The above code outputs:</p>
<div class="language-text highlight"><pre><span></span><code><span id="__span-13-1"><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a>reminder: 5 h
</span></code></pre></div>
<p>And now, a tough question needs an answer. Do we really want modulo operation on physical units
to be consistent with the quotient-remainder theorem and return <code>5 h</code> for <code>5 * h % (120 * min)</code>?</p>
<p>This is exactly why we decided not to follow this hugely surprising path in the <strong>mp-units</strong> library.
The selected approach was also consistent with the feedback from the C++ experts. For example,
this is what Richard Smith said about this issue:</p>
<div class="admonition quote">
<p class="admonition-title">Richard Smith</p>
<p>I think the quotient-remainder property is a less important motivation here than other factors
-- the constraints on <code>%</code> and <code>/</code> are quite different, so they lack the inherent connection they
have for integers. In particular, I would expect that <code>A / B</code> works for all quantities <code>A</code> and <code>B</code>,
whereas <code>A % B</code> is only meaningful when <code>A</code> and <code>B</code> have the same dimension. It seems like
a nice-to-have for the property to apply in the case where both <code>/</code> and <code>%</code> are defined,
but internal consistency of <code>/</code> across all cases seems much more important to me.</p>
<p>I would expect <code>61 min % 1 h</code> to be <code>1 min</code>, and <code>1 h % 59 min</code> to also be <code>1 min</code>, so my
intuition tells me that the result type of <code>A % B</code>, where <code>A</code> and <code>B</code> have the same dimension,
should have the smaller unit of <code>A</code> and <code>B</code> (and if the smaller one doesn't divide
the larger one, we should either use the <code>gcd / std::common_type</code> of the units of
<code>A</code> and <code>B</code> or perhaps just produce an error). I think any other behavior for <code>%</code> is hard to
defend.</p>
<p>On the other hand, for division it seems to me that the choice of unit should probably not affect
the result, and so if we want that <code>5 mm / 120 min = 0 mm/min</code>, then <code>5 h / 120 min == 0 hc</code>
(where <code>hc</code> is a dimensionless "hexaconta", or <code>60x</code>, unit). I don't like the idea of taking
SI base units into account; that seems arbitrary and like it would do the wrong thing as often
as it does the right thing, especially when the units have a multiplier that is very large or
small. We could special-case the situation of a dimensionless quantity, but that could lead to
problematic overflow pretty easily: a calculation such as <code>10 s * 5 GHz * 2 uW</code> would overflow
an <code>int</code> if it produces a dimensionless quantity for <code>10 s * 5 GHz</code>, but it could equally
produce <code>50 G * 2 uW = 100 kW</code> without any overflow, and presumably would if the terms were merely
reordered.</p>
<p>If people want to use integer-valued quantities, I think it's fundamental that you need
to know what the units of the result of an operation will be, and take that into account in how you
express computations; the simplest rule for heterogeneous operators like <code>*</code> or <code>/</code> seems to be that
the units of the result are determined by applying the operator to the units of the operands
-- and for homogeneous operators like <code>+</code> or <code>%</code>, it seems like the only reasonable option is
that you get the <code>std::common_type</code> of the units of the operands.</p>
</div>
<p>To summarize, the modulo operation on physical units has more in common with addition and
division operators than with the quotient-remainder theorem. To avoid surprising results, the
operation uses a common unit to do the calculation and provide its result:</p>
<div class="language-cpp highlight"><pre><span></span><code><span id="__span-14-1"><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a><span class="k">static_assert</span><span class="p">(</span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="p">(</span><span class="mi">120</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">min</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">one</span><span class="p">);</span>
</span><span id="__span-14-2"><a id="__codelineno-14-2" name="__codelineno-14-2" href="#__codelineno-14-2"></a><span class="k">static_assert</span><span class="p">(</span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="p">(</span><span class="mi">120</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">min</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">60</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">min</span><span class="p">);</span>
</span><span id="__span-14-3"><a id="__codelineno-14-3" name="__codelineno-14-3" href="#__codelineno-14-3"></a><span class="k">static_assert</span><span class="p">(</span><span class="mi">61</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">h</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">min</span><span class="p">);</span>
</span><span id="__span-14-4"><a id="__codelineno-14-4" name="__codelineno-14-4" href="#__codelineno-14-4"></a><span class="k">static_assert</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="p">(</span><span class="mi">59</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">min</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">min</span><span class="p">);</span>
</span></code></pre></div>
<h2 id="comparison-against-zero">Comparison against zero<a class="headerlink" href="#comparison-against-zero" title="Permanent link">&para;</a></h2>
<p>In our code, we often want to compare the value of a quantity against zero. For example, we do it
every time we want to ensure that we deal with a non-zero or positive value.</p>
<p>We could implement such checks in the following way:</p>
<div class="language-cpp highlight"><pre><span></span><code><span id="__span-15-1"><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-1"></a><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">q1</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">q2</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">s</span><span class="p">)</span>
</span><span id="__span-15-2"><a id="__codelineno-15-2" name="__codelineno-15-2" href="#__codelineno-15-2"></a><span class="w"> </span><span class="c1">// ...</span>
</span></code></pre></div>
<p>The above would work (assuming we are dealing with the quantity of speed) but could be suboptimal
if the result of <code>q1 / q2</code> is not expressed in <code>m / s</code>. To eliminate the need for conversion, we
need to write:</p>
<div class="language-cpp highlight"><pre><span></span><code><span id="__span-16-1"><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></a><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="k">auto</span><span class="w"> </span><span class="n">q</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">q1</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">q2</span><span class="p">;</span><span class="w"> </span><span class="n">q</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">q</span><span class="p">.</span><span class="n">zero</span><span class="p">())</span>
</span><span id="__span-16-2"><a id="__codelineno-16-2" name="__codelineno-16-2" href="#__codelineno-16-2"></a><span class="w"> </span><span class="c1">// ...</span>
</span></code></pre></div>
<p>but that is a bit inconvenient, and inexperienced users could be unaware of this technique
and its reasons.</p>
<p>For the above reasons, the library provides dedicated interfaces to compare against zero that
follow the naming convention of
<a href="https://en.cppreference.com/w/cpp/utility/compare/named_comparison_functions">named comparison functions</a>
in the C++ Standard Library. The <em>mp-units/compare.h</em> header file exposes the following functions:</p>
<ul>
<li><code>is_eq_zero</code></li>
<li><code>is_neq_zero</code></li>
<li><code>is_lt_zero</code></li>
<li><code>is_gt_zero</code></li>
<li><code>is_lteq_zero</code></li>
<li><code>is_gteq_zero</code></li>
</ul>
<p>Thanks to them, to save typing and not pay for unneeded conversions, our check could be implemented
as follows:</p>
<div class="language-cpp highlight"><pre><span></span><code><span id="__span-17-1"><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-1"></a><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">is_neq_zero</span><span class="p">(</span><span class="n">q1</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">q2</span><span class="p">))</span>
</span><span id="__span-17-2"><a id="__codelineno-17-2" name="__codelineno-17-2" href="#__codelineno-17-2"></a><span class="w"> </span><span class="c1">// ...</span>
</span></code></pre></div>
<div class="admonition tip">
<p class="admonition-title">Tip</p>
<p>Those functions will work with any type <code>T</code> that exposes <code>zero()</code> member function returning
something comparable to <code>T</code>. Thanks to that, we can use them not only with quantities but also
with <a href="https://en.cppreference.com/w/cpp/chrono/duration"><code>std::chrono::duration</code></a> or any other
type that exposes such an interface.</p>
</div>
<h2 id="other-maths">Other maths<a class="headerlink" href="#other-maths" title="Permanent link">&para;</a></h2>
<p>This chapter scopes only on the <code>quantity</code> type's operators. However, there are many named math
functions taking quantities as arguments. Those can be found in the <em>mp-units/math.h</em> header file.
Among others, we can find there the following:</p>
<ul>
<li><code>pow()</code>, <code>sqrt()</code>, <code>cbrt()</code>,</li>
<li><code>exp()</code>,</li>
<li><code>abs()</code>,</li>
<li><code>epsilon()</code>,</li>
<li><code>fma()</code>, <code>fmod()</code>, <code>remainder()</code>,</li>
<li><code>isfinite()</code>, <code>isinf()</code>, <code>isnan()</code>,</li>
<li><code>floor()</code>, <code>ceil()</code>, <code>round()</code>,</li>
<li><code>inverse()</code>,</li>
<li><code>hypot()</code>,</li>
<li><code>sin()</code>, <code>cos()</code>, <code>tan()</code>,</li>
<li><code>asin()</code>, <code>acos()</code>, <code>atan()</code>, <code>atan2()</code>.</li>
</ul>
<p>In the library, we can also find <em>mp-units/random.h</em> header file with all the pseudo-random number
generators working on quantity types.</p>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
Back to top
</button>
</main>
<footer class="md-footer">
<nav class="md-footer__inner md-grid" aria-label="Footer" >
<a href="../dimensionless_quantities/" class="md-footer__link md-footer__link--prev" aria-label="Previous: Dimensionless Quantities">
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</div>
<div class="md-footer__title">
<span class="md-footer__direction">
Previous
</span>
<div class="md-ellipsis">
Dimensionless Quantities
</div>
</div>
</a>
<a href="../generic_interfaces/" class="md-footer__link md-footer__link--next" aria-label="Next: Generic Interfaces">
<div class="md-footer__title">
<span class="md-footer__direction">
Next
</span>
<div class="md-ellipsis">
Generic Interfaces
</div>
</div>
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11z"/></svg>
</div>
</a>
</nav>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
<div class="md-copyright__highlight">
Copyright &copy; 2018-2023 Mateusz Pusz
</div>
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "../../..", "features": ["content.action.edit", "content.action.view", "content.code.annotate", "content.code.copy", "navigation.indexes", "navigation.tabs", "navigation.footer", "navigation.top", "search.highlight", "search.share", "search.suggest", "toc.follow", "toc.integrate"], "search": "../../../assets/javascripts/workers/search.6ce7567c.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": {"provider": "mike"}}</script>
<script src="../../../assets/javascripts/bundle.83f73b43.min.js"></script>
<script src="../../../javascripts/mathjax.js"></script>
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
</body>
</html>