<p>Based on my limited experience, most languages that have rationals as their primary number type simply do not have built-ins for <code>sin</code>,<code>cos</code>,<code>tan</code> and also functions like <code>exp</code> whose results may not always be exactly re-presentable by a rational.</p>
<p>These functions are quite useful though, so I do want to have them.</p>
<p>I'm looking for examples of how other languages handle the precision problem. Should one automatically determine the precision required, or somehow allow customizing this? How do languages create a good developer experience for this while not hurting performance too much?</p>

<math>
How to usefully implement trig (and other irrational functions) on rational primitives
CC BY-SA 4.0
2024-05-28T11:55:33.753Z
You have to make a choice ─ either go symbolic all the way, or have a separate type for approximate numbers. Each choice has its own benefits and drawbacks depending on the context. It depends on what your language is meant for.
kaya3
CC BY-SA 4.0
2024-05-28T13:15:28.323Z
Also consider trigonometric functions scaled by $\pi$. That is, $f(x) = sin(2\pi x)$ and so on. Very useful with rationals. (Don't have their standard name at hand.)
Pablo H
CC BY-SA 4.0
2024-05-28T15:14:24.397Z
Do fixed point numbers as rationals here?
feldentm
CC BY-SA 4.0
2024-05-28T15:21:02.717Z
@feldentm No, my language can have arbitrary precision integers both as the numerator and the denominator. Fixed point only supports power of 2 denominators.
mousetail 'he-him'
CC BY-SA 4.0
2024-05-29T02:22:37.443Z
If you care about precision, it's probably best to represent the results symbolically, e.g. using an ADT that can recursively encode the computation (`Div (Sin (Mul Pi (Int 42))) (Exp (Int 2) (Div (Int 1) (Int 2)))`). Otherwise, you may want to support both "exact" rationals and "inexact" floating points, and fallback to floating points whenever irrational numbers are involved.
tarzh
CC BY-SA 4.0
2024-05-29T02:29:03.890Z
Since you wanted real-world examples: [Computer Algebra Systems (CASs)](https://en.wikipedia.org/wiki/Computer_algebra_system) (e.g. Mathematica), many of which include programming languages, can represent numbers symbolically. [Racket uses "exact" and "inexact" numbers, where the exact numbers are arbitrary-precision rationals](https://docs.racket-lang.org/guide/numbers.html).
tarzh
CC BY-SA 4.0
2024-05-29T04:51:07.420Z
Two things come to mind: (1) there is [an infinite precision representation](https://www.youtube.com/watch?v=LJQgYBQFtSE) that works for all computable numbers (which includes things like pi, e, sqrt(2), ...). (2) Norman Wildberger has some work on trigonometry with rational numbers. He has some controversial views about philosophy of math (he's an ultra-finitist), but he is a mathematician and those views do not invalidate his work. Those views also motivate his work (since, from my understanding, he doesn't "believe in" the real numbers).
David Young
CC BY-SA 4.0
2024-05-29T04:54:19.533Z
Regarding (1): there are limitations to this representation. For instance, the problem of comparing two numbers for equality is only semi-decidable. Regarding (2): I believe Wildberger's trigonometry is partially based on two main ideas: "quadrance" and "spread". "Quadrance" is squared distance (so you no longer have the square root in the def'n). "Spread" is a replacement for traditional measures of angles. I think it is the square of the sine. He has a Youtube channel where he has many videos on these ideas and he's written a book on it as well (which I haven't read yet).
David Young
CC BY-SA 4.0
2024-05-29T05:36:51.457Z
@DavidYoung Interesting, do you know any languages/libraries that implement a representation like that?
mousetail 'he-him'
CC BY-SA 4.0
2024-05-29T14:40:48.500Z
@mousetail There are a couple Haskell packages around that have a representation for computable reals, like [this one](https://hackage.haskell.org/package/numbers-3000.2.0.2/docs/Data-Number-CReal.html). You can see the source for a version of that one [here](https://github.com/cartazio/numbers/blob/master/Data/Number/CReal.hs)
David Young
CC BY-SA 4.0
2024-05-30T05:15:44.617Z
Just as a comment, the usual way that CAS handles exact trigonometry is observing that $\sin (\pi q)$ is algebraic for any rational $q$.
Pseudonym
# How to usefully implement trig (and other irrational functions) on rational primitives
Posted by: username_0 on 2024-05-28
Based on my limited experience, most languages that have rationals as their primary number type simply do not have built-ins for `sin`,`cos`,`tan` and also functions like `exp` whose results may not always be exactly re-presentable by a rational.

These functions are quite useful though, so I do want to have them.

I'm looking for examples of how other languages handle the precision problem. Should one automatically determine the precision required, or somehow allow customizing this? How do languages create a good developer experience for this while not hurting performance too much?
**Tags:** math
> **Comments:**
> **username_1**: You have to make a choice ─ either go symbolic all the way, or have a separate type for approximate numbers. Each choice has its own benefits and drawbacks depending on the context. It depends on what your language is meant for.  
> **username_2**: Also consider trigonometric functions scaled by $\pi$. That is, $f(x) = sin(2\pi x)$ and so on. Very useful with rationals. (Don't have their standard name at hand.)  
> **username_3**: Do fixed point numbers as rationals here?  
> **username_0**: @feldentm No, my language can have arbitrary precision integers both as the numerator and the denominator. Fixed point only supports power of 2 denominators.  
> **username_4**: If you care about precision, it's probably best to represent the results symbolically, e.g. using an ADT that can recursively encode the computation (`Div (Sin (Mul Pi (Int 42))) (Exp (Int 2) (Div (Int 1) (Int 2)))`). Otherwise, you may want to support both "exact" rationals and "inexact" floating points, and fallback to floating points whenever irrational numbers are involved.  
> **username_4**: Since you wanted real-world examples: [Computer Algebra Systems (CASs)](https://en.wikipedia.org/wiki/Computer_algebra_system) (e.g. Mathematica), many of which include programming languages, can represent numbers symbolically. [Racket uses "exact" and "inexact" numbers, where the exact numbers are arbitrary-precision rationals](https://docs.racket-lang.org/guide/numbers.html).  
> **username_5**: Two things come to mind: (1) there is [an infinite precision representation](https://www.youtube.com/watch?v=LJQgYBQFtSE) that works for all computable numbers (which includes things like pi, e, sqrt(2), ...). (2) Norman Wildberger has some work on trigonometry with rational numbers. He has some controversial views about philosophy of math (he's an ultra-finitist), but he is a mathematician and those views do not invalidate his work. Those views also motivate his work (since, from my understanding, he doesn't "believe in" the real numbers).  
> **username_5**: Regarding (1): there are limitations to this representation. For instance, the problem of comparing two numbers for equality is only semi-decidable. Regarding (2): I believe Wildberger's trigonometry is partially based on two main ideas: "quadrance" and "spread". "Quadrance" is squared distance (so you no longer have the square root in the def'n). "Spread" is a replacement for traditional measures of angles. I think it is the square of the sine. He has a Youtube channel where he has many videos on these ideas and he's written a book on it as well (which I haven't read yet).  
> **username_0**: @DavidYoung Interesting, do you know any languages/libraries that implement a representation like that?  
> **username_5**: @mousetail There are a couple Haskell packages around that have a representation for computable reals, like [this one](https://hackage.haskell.org/package/numbers-3000.2.0.2/docs/Data-Number-CReal.html). You can see the source for a version of that one [here](https://github.com/cartazio/numbers/blob/master/Data/Number/CReal.hs)  
> **username_6**: Just as a comment, the usual way that CAS handles exact trigonometry is observing that $\sin (\pi q)$ is algebraic for any rational $q$.  
---
## 0 answers
