-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: math utilities for the frontscope (#177)
* feat: math utilities for the frontscope Adds a new module `shared/math` that has some convenience functions for math in frontscope, especially for working with bigints. Specifically this first revision has safeNumber, for converting to a number with a check for loss of accuracy; floorSqrt for finding a bigint square root; modulo for the mathematician's modulo of bigints; and powmod for calculating a power of a number to some modulus (much more efficiently than exponentiating and then modding). Also provides documentation and tests for the new features and a guide to using bigints in frontscope. Resolves #163. Partially addresses #41. Does the first half of #172. * doc(CONTRIBUTING): make the comment on apis readable on github * feat(math): Natural log for bigints * docs/test: Respond to Kate review
- Loading branch information
Showing
14 changed files
with
594 additions
and
228 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
## Working with bigints | ||
|
||
All of frontscope's Sequence objects return bigints as their elements. The | ||
rationale is that many OEIS entries contain integer values too large to be | ||
accurately represented by JavaScript's `number` type, and attempting to | ||
compute with `number`s would lead to incorrect behavior such as considering | ||
all sufficiently large integers to be even. | ||
|
||
As a result, when working with sequence values you should attempt to use only | ||
the bigint type insofar as possible. | ||
|
||
Here's more information and techniques to facilitate using bigint in your | ||
code: | ||
|
||
- The name of the TypeScript type for bigints is `bigint`. However, when you | ||
want to make a value `v` of some other type into a bigint, you call | ||
`BigInt(v)`. | ||
- Literal values of type `bigint` consist digits followed by a lower-case n, | ||
like 73n for the bigint with value 73, or 0n or -10n, etc. | ||
- Right now unfortunately mathjs does not work on bigints but we are working | ||
on that. | ||
- In the meantime to compensate for the lack of bigints in mathjs, we have a | ||
module (`src/shared/math`) in numberscope to supply some math utilities. | ||
You should familiarize yourself with the | ||
[functions it offers](../src/shared/math.md). | ||
- In particular, if you are forced to convert a bigint to the JavaScript | ||
number type, you should do it with the `safeNumber` function provided by | ||
the math utility module, unless for some structural reason you are | ||
**certain** the bigint won't overflow the number. That will provide | ||
overflow checking and throw an error if accuracy would be lost. Note that | ||
any value you get from the OEIS may be too large to fit in the JavaScript | ||
number type. | ||
- In any math operations, both operands must be of the same type. So | ||
generally prefer converting to bigints any numbers you may need to use in | ||
a calculation with bigints, if possible. | ||
- However, note that the result of dividing one bigint by another is | ||
automatically "floored" to produce an integer result. Be careful to think | ||
if that's what you want; if not, you may need to rearrange your | ||
expressions. For example `x * (3n/5n)` is very different from `(x*3n)/5n` | ||
-- the former is always 0n, but the second will have the value 60n when x | ||
is 100n, for example. | ||
- You can't index an array with a bigint, so that is one case in which you | ||
will be forced to convert to the number type. Since your array will not | ||
have billions of elements, if you have made sure that your bigint is small | ||
enough to index into the array, it will be small enough to safely convert | ||
to a number. | ||
- Use `===` to test if two bigints are equal and `!==` to check if they are | ||
different. As with other operations, you can't use these to compare a | ||
bigint and a number. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.