From 062b01da55e8349521f2d2cdbea3b103ff6ad82b Mon Sep 17 00:00:00 2001 From: Simon Forman Date: Sat, 15 Oct 2022 09:52:58 -0700 Subject: [PATCH] That seems to work: addition and subtraction. --- docs/notebooks/BigInts.ipynb | 254 +++++++++++++++++++++++++++++++---- implementations/bigints.joy | 12 +- 2 files changed, 236 insertions(+), 30 deletions(-) diff --git a/docs/notebooks/BigInts.ipynb b/docs/notebooks/BigInts.ipynb index 5cfdfd9..b906687 100644 --- a/docs/notebooks/BigInts.ipynb +++ b/docs/notebooks/BigInts.ipynb @@ -5077,40 +5077,246 @@ "from-bigint" ] }, + { + "cell_type": "code", + "execution_count": 211, + "id": "3d29ed60", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [] + } + ], + "source": [ + "clear" + ] + }, + { + "cell_type": "markdown", + "id": "cb2fe4bb", + "metadata": {}, + "source": [ + "#### `neg-bigint`" + ] + }, + { + "cell_type": "code", + "execution_count": 212, + "id": "47d10c16", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [] + } + ], + "source": [ + "[neg-bigint [not] infra] inscribe" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "781a1ed2", + "metadata": {}, + "outputs": [], + "source": [ + "123 " + ] + }, + { + "cell_type": "code", + "execution_count": 213, + "id": "e2bf4564", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-123" + ] + } + ], + "source": [ + "to-bigint neg-bigint from-bigint" + ] + }, + { + "cell_type": "code", + "execution_count": 214, + "id": "9b4c3ea7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "123" + ] + } + ], + "source": [ + "to-bigint neg-bigint from-bigint" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7c4edc9a", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8d467543", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5722d274", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d08a5ea1", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4e18e84a", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b72d58e6", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f134ab23", + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "markdown", "id": "f2b707c1", "metadata": {}, "source": [ "## Appendix: Source Code\n", + " clear\n", + " [base 2147483648]\n", + " [ditch-empty-list [bool] [popd] [pop] ifte]\n", + " [bool-to-int [0] [1] branch]\n", + " [uncons-two [uncons] ii swapd]\n", + " [sandwich swap [cons] dip swoncat]\n", "\n", - " base 2147483648\n", - " ditch-empty-list [bool] [popd] [pop] ifte\n", - " bool-to-int [0] [1] branch\n", - " uncons-two [uncons] ii swapd\n", + " [digitalize [0 <=] [pop []] [base divmod swap] [i cons] genrec]\n", + " [to-bigint [!-] [abs digitalize] cleave cons]\n", "\n", - " add-with-carry _a0 _a1\n", - " _a0 [bool-to-int] dipd + +\n", - " _a1 base [mod] [>=] clop\n", + " [prep rest 1 0 rolldown]\n", + " [from-bigint' [next-digit] step popd]\n", + " [next-digit [increase-power] [accumulate-digit] clop popdd]\n", + " [increase-power popop base *]\n", + " [accumulate-digit rolldown * +]\n", "\n", - " add-carry-to-digits [pop not] [popd] [_actd_R0] [i cons] genrec\n", - " _actd_R0 [bool] [_actd_R0.then] [_actd_R0.else] ifte\n", - " _actd_R0.else popd 1 false rolldown\n", - " _actd_R0.then 0 swap uncons [add-with-carry] dip\n", + " [sign-int [first] [prep from-bigint'] cleave]\n", + " [neg-if-necessary swap [neg] [] branch]\n", + " [from-bigint sign-int neg-if-necessary]\n", "\n", - " add-digits initial-carry add-digits'\n", - " initial-carry false rollup\n", - " add-digits' [P] [THEN] [R0] [i cons] genrec\n", - " P [bool] ii & not\n", - " THEN [P'] [THEN'] [ELSE] ifte\n", - " R0 uncons-two [add-with-carry] dipd\n", - " P' [bool] ii |\n", - " THEN' ditch-empty-list add-carry-to-digits\n", - " ELSE pop swap [] [1 swons] branch\n", + " [add-with-carry _add-with-carry0 _add-with-carry1]\n", + " [_add-with-carry0 [bool-to-int] dipd + +]\n", + " [_add-with-carry1 base [mod] [>=] clop]\n", "\n", - " same-sign [first] ii xor not\n", - " add-like-bigints [uncons] dip rest add-digits cons\n", - " add-bigints [same-sign] [add-like-bigints] [1 0 /] ifte" + " [add-carry-to-digits [pop not] [popd] [_actd_R0] [i cons] genrec]\n", + " [_actd_R0 [bool] [_actd_R0.then] [_actd_R0.else] ifte]\n", + " [_actd_R0.else popd 1 false rolldown]\n", + " [_actd_R0.then 0 swap uncons [add-with-carry] dip]\n", + "\n", + " [add-digits initial-carry add-digits']\n", + " [initial-carry false rollup]\n", + "\n", + " [add-digits' [P] [THEN] [R0] [R1] genrec]\n", + " [P [bool] ii & not]\n", + " [THEN [P'] [THEN'] [ELSE] ifte]\n", + " [R0 uncons-two [add-with-carry] dipd]\n", + " [R1 i cons]\n", + " [P' [bool] ii |]\n", + " [THEN' ditch-empty-list add-carry-to-digits]\n", + " [ELSE pop swap [] [1 swons] branch]\n", + "\n", + " [same-sign [first] ii xor not]\n", + " [add-like-bigints [uncons] dip rest add-digits cons]\n", + " [add-bigints [same-sign] [add-like-bigints] [neg-bigint sub-like-bigints] ifte]\n", + "\n", + " [build-two-list-combiner _btlc0 _btlc1 [i cons]]\n", + " [_btlc0.0 [[ditch-empty-list] swoncat] dip]\n", + " [_btlc0.1 [pop] swoncat]\n", + " [_btlc0.3 [_btlc0.0 _btlc0.1] dip]\n", + " [_btlc0.4 [uncons-two] [dipd] sandwich]\n", + " [_btlc0 _btlc0.3 _btlc0.4]\n", + " [_btlc1 [[ifte] ccons [P'] swons [P] swap] dip]\n", + "\n", + " [carry [] [1 swons] branch]\n", + "\n", + " [compare-pairs [bool not] [pop false] [[first [>=] infrst] [pop true]] [[rest] swoncat ifte] genrec]\n", + " [xR1 uncons-two [unit cons swons] dipd]\n", + " [xP [bool] ii & not]\n", + " [BASE [bool] [popop pop true] [[pop bool] [popop pop false] [popop compare-pairs] ifte] ifte]\n", + " [gt-bigint <<{} [xP] [BASE] [xR1] tailrec]\n", + " [check-gt [gt-bigint] [swap [not] dipd] [] ifte]\n", + "\n", + " [sub-carry pop]\n", + "\n", + " [sub-carry-from-digits [pop not] [popd] [_scfd_R0] [i cons-but-not-leading-zeroes] genrec] inscribe\n", + " [_scfd_R0 uncons 0 swap [sub-with-carry] dip] inscribe\n", + " [cons-but-not-leading-zeroes [P'] [cons] [popd] ifte]\n", + "\n", + " [sub-with-carry _sub-with-carry0 _sub-with-carry1]\n", + " [_sub-with-carry0 rolldown bool-to-int [-] ii]\n", + " [_sub-with-carry1 [base + base mod] [0 <] cleave]\n", + "\n", + " [sub-like-bigints [uncons] dip rest check-gt sub-digits cons]\n", + " [sub-digits initial-carry sub-digits']\n", + "\n", + " enstacken [inscribe] step\n", + "\n", + " [add-carry-to-digits]\n", + " [swap carry]\n", + " [add-with-carry]\n", + " build-two-list-combiner\n", + " [genrec] ccons ccons\n", + " [add-digits'] swoncat\n", + " inscribe\n", + "\n", + " [sub-carry-from-digits]\n", + " [swap sub-carry]\n", + " [sub-with-carry]\n", + " build-two-list-combiner\n", + " [genrec] ccons ccons\n", + " [sub-digits'] swoncat\n", + " inscribe\n" ] }, { @@ -5122,7 +5328,7 @@ "\n", "So far I have three formats for Joy source:\n", "\n", - "- `def.txt` is a list of definitions (UTF-8), one per line, with no special marks (like above.)\n", + "- `def.txt` is a list of definitions (UTF-8), one per line, with no special marks.\n", "- `foo ≡ bar baz...` lines in the `joy.py` embedded definition text, because why not? (Sometimes I use `==` instead of `≡` mostly because some tools can't handle the Unicode glyph. Like converting this notebook to PDF via LaTeX just omitted them.)\n", "- `[name body] inscribe` Joy source code that literally defines new words in the dictionary at runtime. A text of those commands can be fed to the interpreter to customize it without any special processing (like the other two formats require.)\n", "\n", diff --git a/implementations/bigints.joy b/implementations/bigints.joy index 27c997b..e890fca 100644 --- a/implementations/bigints.joy +++ b/implementations/bigints.joy @@ -18,6 +18,8 @@ clear [neg-if-necessary swap [neg] [] branch] [from-bigint sign-int neg-if-necessary] +[neg-bigint [not] infra] + [add-with-carry _add-with-carry0 _add-with-carry1] [_add-with-carry0 [bool-to-int] dipd + +] [_add-with-carry1 base [mod] [>=] clop] @@ -41,9 +43,9 @@ clear [same-sign [first] ii xor not] [add-like-bigints [uncons] dip rest add-digits cons] -[add-bigints [same-sign] [add-like-bigints] [1 0 /] ifte] +[add-bigints [same-sign] [add-like-bigints] [neg-bigint sub-like-bigints] ifte] -[build-two-list-combiner _btlc0 _btlc1 [i cons]] +[build-two-list-combiner _btlc0 _btlc1 [[i cons] genrec] ccons cons] [_btlc0.0 [[ditch-empty-list] swoncat] dip] [_btlc0.1 [pop] swoncat] [_btlc0.3 [_btlc0.0 _btlc0.1] dip] @@ -73,13 +75,14 @@ clear [sub-like-bigints [uncons] dip rest check-gt sub-digits cons] [sub-digits initial-carry sub-digits'] +[sub-bigints [same-sign] [sub-like-bigints] [neg-bigint add-like-bigints] ifte] + enstacken [inscribe] step [add-carry-to-digits] [swap carry] [add-with-carry] build-two-list-combiner -[genrec] ccons ccons [add-digits'] swoncat inscribe @@ -87,8 +90,5 @@ inscribe [swap sub-carry] [sub-with-carry] build-two-list-combiner -[genrec] ccons ccons [sub-digits'] swoncat inscribe - -