# \[ANN\] UnitfulAngles: a unitful units package for angles

**URL:** <https://discourse.julialang.org/t/ann-unitfulangles-a-unitful-units-package-for-angles/5065>\
**Category:** Community\
**Tags:** package, announcement, unitful\
**Created:** [July 25, 2017, 7:18pm UTC](https://discourse.julialang.org/t/ann-unitfulangles-a-unitful-units-package-for-angles/5065 "2017-07-25T19:18:19Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [July 25, 2017, 7:18pm UTC](https://discourse.julialang.org/t/ann-unitfulangles-a-unitful-units-package-for-angles/5065/1 "2017-07-25T19:18:19Z")

</div>

Hello people!  
So, after a few iterations ([1](https://discourse.julialang.org/t/why-an-angles-jl-package-is-not-a-great-idea/4973), [2](https://github.com/yakir12/Angles.jl/), and [3](https://discourse.julialang.org/t/should-there-be-a-native-angle-type/4611)) and some thought, here is a supplemental units package for `Unitful.jl` that deals with angles: [`UnitfulAngles.jl`](https://github.com/yakir12/UnitfulAngles.jl).

I want to register it as soon as I solve [issue #1](https://github.com/yakir12/UnitfulAngles.jl/issues/1).

Thoughts, comments, etc are very much appreciated!

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [July 26, 2017, 1:49pm UTC](https://discourse.julialang.org/t/ann-unitfulangles-a-unitful-units-package-for-angles/5065/2 "2017-07-26T13:49:16Z")

</div>

Nice work.

If you let `tan(1u"octant")` map to `tand(45)` instead of `tan((1//4)π)`, you will get better accuracy.

I’m not sure why you introduce `myRad` and `my°`. Why not use the radians and degrees already provided by Unitful?

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [July 26, 2017, 2:38pm UTC](https://discourse.julialang.org/t/ann-unitfulangles-a-unitful-units-package-for-angles/5065/3 "2017-07-26T14:38:01Z")

</div>

> [@Per](#):
>
> Nice work.
> 
> If you let `tan(1u"octant")` map to `tand(45)` instead of `tan((1//4)π)`, you will get better accuracy.

Good catch on the tan **d** (I only took care of the cosd and sind).

> [@](#):
>
> I’m not sure why you introduce `myRad` and `my°`. Why not use the radians and degrees already provided by Unitful?

I didn’t base my angular system on the one already provided in Unitful.jl because tons of the units here can be expressed as a rational number of the full turn. Unitful.jl’s approach was to base the angles on radians. While that makes total sense, it feels like a shame to lose accuracy by using the radians from Unitful.jl.

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [July 26, 2017, 2:58pm UTC](https://discourse.julialang.org/t/ann-unitfulangles-a-unitful-units-package-for-angles/5065/4 "2017-07-26T14:58:05Z")

</div>

The degree from Unitful does not lose accuracy. (For example, `sin(180u"°")` returns `0.0`.) It should be safe to define a turn as 360 of Unitful’s degrees.

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [July 26, 2017, 3:19pm UTC](https://discourse.julialang.org/t/ann-unitfulangles-a-unitful-units-package-for-angles/5065/5 "2017-07-26T15:19:27Z")

</div>

I played around, and you are of course right. But I don’t understand:  
We can divide the full turn by integers OR by irrational numbers. The first choice must be more accurate because we can accurately represent it in `Julia`. If I set the base unit for angles as radians (which is not accurately represented as a float), then all the units will be slightly off. If I base it on the full-turn, then only radians and diameter-parts will be slightly off (which they are already).  
I’m obviously wrong here somewhere… What am I missing? 😕

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [July 26, 2017, 3:54pm UTC](https://discourse.julialang.org/t/ann-unitfulangles-a-unitful-units-package-for-angles/5065/6 "2017-07-26T15:54:52Z")

</div>

When you represent a “degree” as π/180 and a “turn” as 2π, the conversion from turns to degrees will still be exact, because the conversion factor, computed as (2π)/(π/180) still comes out to 360.0 exactly.

Conversion in the other direction might not be exact, because 1/360 is not exactly representable in floating point. If you want to do exact unit conversion with rational numbers, I guess you could define additional methods for `Unitful.convfact`. (Or just submit a PR to Unitful, asking them to make a “turn” the reference unit for angles.)

Note that your current implementation gives problems whenever someone tries to convert between Unitful’s degrees or radians and your units. For example: `uconvert(u"rad", 1*u"myRad")` comes out to `0.15915494309189535 rad`.

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [July 26, 2017, 5:43pm UTC](https://discourse.julialang.org/t/ann-unitfulangles-a-unitful-units-package-for-angles/5065/7 "2017-07-26T17:43:55Z")

</div>

When I think about it, probably the best thing would be to make all of this a PR to Unitful, instead of a separate package.

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [July 26, 2017, 6:02pm UTC](https://discourse.julialang.org/t/ann-unitfulangles-a-unitful-units-package-for-angles/5065/8 "2017-07-26T18:02:55Z")

</div>

The argument _for_ a PR would be that these angular goodies would be as useful for everyone as other things in [pkgdefaults.jl](https://github.com/ajkeller34/Unitful.jl/blob/master/src/pkgdefaults.jl). The argument _against_ it would be that 14 additional degree units warrants its own package.  
I’m really OK with whichever. Maybe @ajkeller34 can weight in on this?

---

<div class="post-metadata">

**Author:** ![barche](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/barche/32/79_2.png) [@barche](https://discourse.julialang.org/u/barche)\
**Post date:** [July 26, 2017, 6:57pm UTC](https://discourse.julialang.org/t/ann-unitfulangles-a-unitful-units-package-for-angles/5065/9 "2017-07-26T18:57:18Z")

</div>

I’m also in favor of complete integration into Unitful, it is designed in such a way that the number of units available doesn’t really pose any problems.

---

<div class="post-metadata">

**Author:** ![Michael\_Eastwood](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/michael_eastwood/32/669_2.png) [@Michael\_Eastwood](https://discourse.julialang.org/u/Michael_Eastwood)\
**Post date:** [July 26, 2017, 8:33pm UTC](https://discourse.julialang.org/t/ann-unitfulangles-a-unitful-units-package-for-angles/5065/10 "2017-07-26T20:33:01Z")

</div>

I disagree with this. Unitful has been designed with the goal of making it possible for the user to define their own units easily. Adding a bunch of esoteric units to the default package just increases the likelihood that the unit abbreviations will collide. The user currently doesn’t have any real control over what is added to the `u"..."` macro namespace.

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [July 26, 2017, 9:36pm UTC](https://discourse.julialang.org/t/ann-unitfulangles-a-unitful-units-package-for-angles/5065/11 "2017-07-26T21:36:55Z")

</div>

Maybe some middle-ground would make sense?

Make a PR for `Unitful.jl` with these:

- halfTurn “π”
- the `sinpi` versions of the trigonometric functions for this halfTurn unit
- the inverse functions returning angle units

and keep the following in a separate `UnitfulAngles.jl` package:

- `Turn`, `Quadrant`, `Sextant`, `Octant`, `ClockPosition`, `HourAngle`, `CompassPoint`, `Hexacontade`, `BinaryRadian`, `DiameterPart`, `Gradian`, `Arcminute`, and `Arcsecond`.
- the `sinpi` and `asin` for those
- time - angle conversion

Too fragmented? Perfect?

---

<div class="post-metadata">

**Author:** ![ajkeller34](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ajkeller34/32/4416_2.png) [@ajkeller34](https://discourse.julialang.org/u/ajkeller34)\
**Post date:** [July 26, 2017, 11:31pm UTC](https://discourse.julialang.org/t/ann-unitfulangles-a-unitful-units-package-for-angles/5065/12 "2017-07-26T23:31:16Z")

</div>

I would prefer to keep these definitions in UnitfulAngles.jl, pretty much for the reasons @Michael_Eastwood mentioned. Also, I’m wary to maintain/test a lot of units that I may never use personally, which is one of several reasons why I made it possible to extend Unitful using additional packages. I imagine people in need of specialty angle units wouldn’t mind the additional `using UnitfulAngles`.

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [July 27, 2017, 5:28am UTC](https://discourse.julialang.org/t/ann-unitfulangles-a-unitful-units-package-for-angles/5065/13 "2017-07-27T05:28:01Z")

</div>

Well then, I’ll fix up `UnitfulAngles.jl` and register it then. Thanks for all the input people!

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [July 27, 2017, 6:25am UTC](https://discourse.julialang.org/t/ann-unitfulangles-a-unitful-units-package-for-angles/5065/14 "2017-07-27T06:25:31Z")

</div>

@ajkeller34 Would you still accept a PR changing the angle reference from 1 radian to 2π radians? That would make it possible for 3rd party packages like UnitfulAngles to provide exact conversion between rational numbers with units that are expressed in fractions of a turn.

---

<div class="post-metadata">

**Author:** ![ajkeller34](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ajkeller34/32/4416_2.png) [@ajkeller34](https://discourse.julialang.org/u/ajkeller34)\
**Post date:** [July 27, 2017, 8:36pm UTC](https://discourse.julialang.org/t/ann-unitfulangles-a-unitful-units-package-for-angles/5065/15 "2017-07-27T20:36:09Z")

</div>

“Reference units” are only used in Unitful when you define a new dimension, as an implementation detail. Angles are dimensionless, so there are no reference units for angles. I defined `1u"rad" == 1` because anything else would give incorrect results (if I converted `2π*u"rad" * 1u"m"` into units of `m`, that had better be equal to `2π*u"m"`). I think @yakir12 realized this in his most recent commit. He could have equivalently defined a turn as `2π` instead of `2π*u"rad"` if he wanted independence from units defined in Unitful, but I don’t think there is a difference in the resulting behavior.
