Skip to content

Commit

Permalink
feat: math utilities for the frontscope (#177)
Browse files Browse the repository at this point in the history
* 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
gwhitney authored Oct 27, 2022
1 parent fa9566b commit 79482f6
Show file tree
Hide file tree
Showing 14 changed files with 594 additions and 228 deletions.
10 changes: 8 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,16 @@ applies to other repos as well.)
1. [Create a fork of the numberscope/frontscope repo](./doc/working-with-git-and-github.md#create-a-fork).
2. [Clone your fork of numberscope/frontscope](./doc/working-with-git-and-github.md#clone-a-repo).
3. [Create a branch for your contribution](./doc/working-with-git-and-github.md#create-a-branch).
4. [Read about basic Git operations](./doc/working-with-git-and-github.md#basic-git-operations).
4. If you are unfamilar with them or would like a refresher,
[read about basic Git operations](./doc/working-with-git-and-github.md#basic-git-operations).
5. [Push your branch to GitHub](./doc/working-with-git-and-github.md#push-a-branch).
6. [Read Numberscope's coding principles guide](./doc/code-principles.md).
7. [Read Numberscope's style guide](./doc/code-style.md).
7. [Read Numberscope's style guide](./doc/code-style.md). You should also
familiarize yourself with frontscope's internal code structure and APIs.
Documentation on these topics is generally incorporated into the relevant
source files (see [this example](src/shared/math.ts)). However, it is all
gathered in the "Internal code and APIs" section of the navigation bar in
the [online docs](https://numberscope.colorado.edu/doc).
8. [Work through Numberscope's pull request checklist](./doc/pull-request-checklist.md).
9. [Submit a pull request](./doc/working-with-git-and-github.md#submit-a-pull-request).

Expand Down
49 changes: 49 additions & 0 deletions doc/working-with-bigints.md
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.
6 changes: 5 additions & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ nav:
- doc/code-style.md
- doc/pull-request-checklist.md
- doc/visual-studio-code-setup.md
- Internal code and APIs:
- doc/working-with-bigints.md
- src/shared/math.md
- Other Information:
- ... | flat | doc/*.md
docs_dir: doc
Expand All @@ -41,7 +44,8 @@ plugins:
- '.spec.ts'
- 'LICENSE.md'
ignore_folders: [node_modules, dist, coverage]
include_extensions: ['.png']
include_extensions: ['.png', 'math.ts']
extract_on_copy: true
merge_docs_dir: false
semiliterate:
- pattern: '\.ts' # Standard in-code markup
Expand Down
Loading

0 comments on commit 79482f6

Please sign in to comment.