Magnitude - The Au units library (2024)

Magnitude is a family of monovalue types representing positive realnumbers. These values can be multiplied, divided, and raised to (rational) powers, and thisarithmetic always takes place at compile time. Values can also be converted to more standardnumeric types, such as double and int, as long as the receiving type can represent themagnitude’s value faithfully.

The core motivation is to represent ratios of different units that have the same dimension. Asa corollary, any unit can be scaled by a Magnitude to make a new unit of the same dimension.

Forming magnitudes

There are 3 valid ways for end users to form a Magnitude instance.

  1. Magnitude - The Au units library (1) Using the mag<N>() helper to form the canonical representation of the integer N.
  2. Magnitude - The Au units library (2) Writing Magnitude<MyConstant>{}, where MyConstant is a valid irrational magnitude base. (See the custom bases section below for more details.)
  3. Magnitude - The Au units library (3) Forming products, quotients, powers, and roots of other valid Magnitude instances.

The following is a valid, but dis-preferred way to form a Magnitude.

  • Magnitude - The Au units library (4) Magnitude<>.
    • Explanation: This represents the number 1, but it’s less readable than writing mag<1>().

The following are not valid ways to form a Magnitude.

  • Magnitude - The Au units library (5) Magnitude<Pi, MyConstant>.
    • Explanation: Do not supply a manual sequence of template parameters. Magnitude has strict ordering requirements on its template parameters. The approved methods listed above are guaranteed to satisfy these requirements.
  • Magnitude - The Au units library (6) Magnitude<Prime<3>>.
    • Explanation: Do not supply integer bases manually. Integers are represented by their prime factorization, which is performed automatically. Instead, form integers, rationals, and their powers only by starting with valid Magnitude instances, and performing arithmetic operations as in option 3 above.

Below, we give more details on several concepts mentioned above.

mag<N>()

mag<N>() gives an instance of the unique, canonical Magnitude type that represents the positiveinteger N.

More detail on integral Magnitude representations

Integers are stored as their prime factorization. For example, 18 would be stored as the typeMagnitude<Prime<2>, Pow<Prime<3>, 2>>, because 18 = 2 \cdot 3^2.

mag<N>() automatically performs the prime factorization of N, and constructs a well-formedMagnitude.

Custom bases

Magnitude can handle some irrational numbers. This even includes some transcendental numbers,such as \pi. Because Magnitude is closed under products and rational powers, this means that wealso automatically support related values such as \pi^2, \frac{1}{\sqrt{2\pi}}, and so on.

What irrational numbers can Magnitude not handle?

A common example is any that are formed by addition. For example, (1 + \sqrt{2}) cannot berepresented by Magnitude. Recall that Magnitude is designed to support products andrational powers, since these are the most important operations in quantity calculus.

It is tempting to want a better representation — one which supports full symbolic algebra.Perhaps such a representation could be designed. However, we haven’t seen any real world usecases for it. The current Magnitude implementation already handles the most critical usecases, such as handling \pi, which most units libraries have traditionally struggled tosupport.

Because of its importance for angular variables, \pi is supported natively in the library, via theirrational magnitude base, Pi. To define a magnitude instance for \pi, you can write:

constexpr auto PI = Magnitude<Pi>{};

If you need to represent an irrational number which can’t be formed via any product of powers of theexisting Magnitude types — namely, integers and \pi — then you can define a new irrationalmagnitude base. This is a struct with the following member:

  • static constexpr long double value(): the best approximation of your constant’s value in the long double storage type.
Important information for defining your own constant

If you return a literal, you must add L on the end. Otherwise it will be interpreted asdouble, and will lose precision.

Here are the results of one example which was run on an arbitrary development machine.

No suffixL suffix
Literal3.1415926535897932383.141592653589793238L
Actual Value3.1415926535897931153.141592653589793238

The un-suffixed version has lost several digits of precision. (The precise amount will dependon the computer architecture being used.)

Each time you add a new irrational magnitude base, you must make sure that it’s independent:that is, that it can’t be formed as any product of rational powers of existing Magnitude types.

Extracting values

As a monovalue type, Magnitude can only hold one value. There areno computations we can perform at runtime; everything happens at compile time. What we can do isto extract that represented value, and store it in a more conventional numeric type, such as intor double.

To extract the value of a Magnitude instance m into a given numeric type T, callget_value<T>(m). Here are some important aspects of this utility.

  1. The computation takes place completely at compile time.
  2. The computation takes place in the widest type of the same kind. (That is, when T is floating point we use long double, and when T is integral we use std::intmax_t or std::uintmax_t according to the signedness of T.)
  3. If T cannot hold the value represented by m, we produce a compile time error.
Example: float and \pi^3

Suppose you are running on an architecture which has hardware support for float, but uses slowsoftware emulation for double and long double. With Magnitude and get_value, you canget the best of both worlds:

  • The computation gets performed at compile time in long double, giving extra precision.
  • The result gets cast to float and stored as a program constant.

Thus, if you have a magnitude instance PI, then get_value<float>(pow<3>(PI)) will be muchmore accurate than storing \pi in a float, and cubing it — yet, there will be no loss inruntime performance.

Checking for representability

If you need to check whether your magnitude m can be represented in a type T, you can callrepresentable_in<T>(m). This function is constexpr compatible.

Example: integer and non-integer values

Here are some example test cases which will pass.

EXPECT_TRUE(representable_in<int>(mag<1>()));// (1 / 2) is not an integer.EXPECT_FALSE(representable_in<int>(mag<1>() / mag<2>()));EXPECT_TRUE(representable_in<float>(mag<1>() / mag<2>()));
Example: range of the type

Here are some example test cases which will pass.

EXPECT_TRUE(representable_in<uint32_t>(mag<4'000'000'000>()));// 4 billion is larger than the max value representable in `int32_t`.EXPECT_FALSE(representable_in<int32_t>(mag<4'000'000'000>()));

Note that this function’s return value also depends on whether we can compute the value, not justwhether it is representable. For example, representable_in<double>(sqrt(mag<2>())) is currentlyfalse, because we haven’t yet added support for computing rational base powers.

Operations

These are the operations which Magnitude supports. Because it is a monovaluetype, the value can take the form of either a type or an instance.In what follows, we’ll use this convention:

  • Capital identifiers (M, M1, M2, …) refer to types.
  • Lowercase identifiers (m, m1, m2, …) refer to instances.

Equality comparison

Result: A bool indicating whether two Magnitude values represent the same number.

Syntax:

  • For types M1 and M2:
    • std::is_same<M1, M2>::value
  • For instances m1 and m2:
    • m1 == m2 (equality comparison)
    • m1 != m2 (inequality comparison)

Multiplication

Result: The product of two Magnitude values.

Syntax:

  • For types M1 and M2:
    • MagProductT<M1, M2>
  • For instances m1 and m2:
    • m1 * m2

Division

Result: The quotient of two Magnitude values.

Syntax:

  • For types M1 and M2:
    • MagQuotientT<M1, M2>
  • For instances m1 and m2:
    • m1 / m2

Powers

Result: A Magnitude raised to an integral power.

Syntax:

  • For a type M, and an integral power N:
    • MagPowerT<M, N>
  • For an instance m, and an integral power N:
    • pow<N>(m)

Roots

Result: An integral root of a Magnitude.

Syntax:

  • For a type M, and an integral root N:
    • MagPowerT<M, 1, N> (because the N^\text{th} root is equivalent to the \left(\frac{1}{N}\right)^\text{th} power)
  • For an instance m, and an integral root N:
    • root<N>(m)

Helpers for powers and roots

Magnitudes support all of the power helpers. So, for example, fora magnitude instance m, you can write sqrt(m) as a more readable alternative to root<2>(m).

Traits

These traits provide information, at compile time, about the number represented by a Magnitude.

Integer test

Result: A bool indicating whether a Magnitude represents an integer (true if it does;false otherwise).

Syntax:

  • For a type M:
    • IsInteger<M>::value
  • For an instance m:
    • is_integer(m)

Rational test

Result: A bool indicating whether a Magnitude represents a rational number (true if itdoes; false otherwise).

Syntax:

  • For a type M:
    • IsRational<M>::value
  • For an instance m:
    • is_rational(m)

Integer part

Result: The integer part of a Magnitude, which is another Magnitude.

For example, the “integer part” of \frac{\sqrt{18}}{5\pi} would be 3, because \sqrt{27}= 3\sqrt{2}, and 3 is the integer part of 3\sqrt{2}.

If the input magnitude is an integer, then this operation is the identity.

If the input magnitude is not an integer, then this operation produces the largest integer factorthat can be extracted from the numerator (that is, the base powers with positive exponent).1

Syntax:

  • For a type M:
    • IntegerPartT<M>
  • For an instance m:
    • integer_part(m)

Numerator (integer part)

Result: The numerator we would have if a Magnitude were written as a fraction. This result isanother Magnitude.

For example, the “numerator” of \frac{3\sqrt{3}}{5\pi} would be 3\sqrt{3}.

Syntax:

  • For a type M:
    • NumeratorT<M>
  • For an instance m:
    • numerator(m)

Denominator (integer part)

Result: The denominator we would have if a Magnitude were written as a fraction. This result isanother Magnitude.

For example, the “denominator” of \frac{3\sqrt{3}}{5\pi} would be 5\pi.

Syntax:

  • For a type M:
    • DenominatorT<M>
  • For an instance m:
    • denominator(m)
  1. The concept integer_part() is conceptually ambiguous when applied to non-integers. So, too,for numerator() and denominator() applied to irrational numbers. These utilities serve twopurposes. First, they provide a means for checking whether a given magnitude is a member of theunambiguous set — that is, we can check whether a magnitude is an integer by checking whether it’sequal to its “integer part”. Second, they enable us to automatically construct labels formagnitudes, by breaking them into the same kinds of pieces that a human reader would expect.

Magnitude - The Au units library (2024)

References

Top Articles
Geese For Sale On Craigslist Near Me
8Muses Giantess
Citi Trends Watches
C Chord for Ukulele: Variations, Styles, and Techniques
Saccone Joly Gossip
T Mobile Rival Crossword Clue
Barber Gym Quantico Hours
Tinyzonehd
Big 12 Officiating Crew Assignments 2022
Coolmathgames.comool Math
Uptown Cheapskate Fort Lauderdale
Fairwinds Shred Fest 2023
Precision Garage Door Long Island
Nissan 300Zx For Sale Craigslist
Shooters Lube Discount Code
Rogers Breece Obituaries
These Mowers Passed the Test and They’re Ready To Trim Your Lawn
Myzmanim Highland Park Nj
Alishbasof
Taxi Driver Kdrama Dramacool
35 Best Anime Waifus Of All Time: The Ultimate Ranking – FandomSpot
Adventhealth Employee Handbook 2022
Mta Bus Forums
Cocaine Bear Showtimes Near Harkins Cerritos
Massage Parlor Columbus Ohio
SIM Cards, Phone Cards & SIM Cards, Cell Phones & Accessories
Walmart Phone Number Auto Center
What You Need to Know About County Jails
Espn Masters Leaderboard
Yesmovie.nm
Uhaul L
Aunt Nettes Menu
Cluster Truck Unblocked Wtf
Uhauldealer.com Login Page
Sentara Norfolk General Visiting Hours
Does Walmart have Affirm program? - Cooking Brush
Guide for The Big Con
Davis Fire Friday live updates: Community meeting set for 7 p.m. with Lombardo
Dpsmypepsico
How To Get Stone Can In Merge Mansion 2022
Drugst0Recowgirl Leaks
Fisher-Cheney Funeral Home Obituaries
Dyi Urban Dictionary
Did You Hear About Worksheet Answers Page 211
California wildfires: Bridge Fire explodes in size; man arrested in connection with Line Fire
What Is Opm1 Treas 310 Deposit
Waffle House Gift Card Cvs
Blow Dry Bar Boynton Beach
James in Spanish | Spanish to Go
C-Reactive Protein (CRP) Test Understand the Test & Your Results
7-11 Paystub Portal
ओ कान्हा अब तो मुरली की O Kanha Ab To Murli Ki Lyrics
Latest Posts
Article information

Author: Dean Jakubowski Ret

Last Updated:

Views: 6183

Rating: 5 / 5 (70 voted)

Reviews: 93% of readers found this page helpful

Author information

Name: Dean Jakubowski Ret

Birthday: 1996-05-10

Address: Apt. 425 4346 Santiago Islands, Shariside, AK 38830-1874

Phone: +96313309894162

Job: Legacy Sales Designer

Hobby: Baseball, Wood carving, Candle making, Jigsaw puzzles, Lacemaking, Parkour, Drawing

Introduction: My name is Dean Jakubowski Ret, I am a enthusiastic, friendly, homely, handsome, zealous, brainy, elegant person who loves writing and wants to share my knowledge and understanding with you.