-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from Ton-Dynasty:math/float
feat: Add document for float library
- Loading branch information
Showing
7 changed files
with
160 additions
and
7 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
{ | ||
"label": "Tutorial - Jetton", | ||
"position": 1, | ||
"position": 2, | ||
"link": { | ||
"type": "generated-index" | ||
} | ||
|
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,71 @@ | ||
--- | ||
sidebar_position: 1 | ||
--- | ||
|
||
# Fixed Point Float | ||
Float library is implemented in FunC for the consideration of gas efficiency. Our implementation takes int128 as input and shifts it left by 64 bits, resulting a fixed $64$ bit space for storing decimals. Take number $7$ as example, when user transforms integer $7$ into float format, the output value will be $7*2^{64}$. | ||
|
||
## Overview | ||
Same as solidity, both FunC and Tact do not support float datatype. However, what if our DeFi application requires to compute some interest rate in a float format? To address this issue, early developers in Solidity adopt a fixed point floating point method, which is relatively easy and gas efficient in comparison with `IEEE 754` format. The basic idea is multiplying a number by a large constant to simulate a decimal points, effectively shifting the decimal place to the right. | ||
|
||
For example, if we need to represent $3.14$ in smart contract, we could easily multiply it by $1000$ (shifting the decimals three place to the right), to get $3140$ as an integer. This approach simplifies computations while maintaining precision, as long as the developers carefully manage the scaling factor throughout the calculations. It is noteworthy we can substitude the constant $1000$ for any arbitrary number, thus, we can use binary shift operator to further reduce the computation complexity. In order to preserve a sufficient range to represent almost all rates in developing, we choose $2^{64}$ for the constant, which is equivalent to shift the origin number 64 bit left by the operator `<<`. | ||
|
||
## Case Study | ||
To explain the arithmetic (especially multiplication and division) in a simple term, we will introduce our usage step by step with elaboration. We take number $2$, $7$ and scaling factor $2^{64}$ for example in this section. | ||
|
||
### Multiplication | ||
Multiply $2$ by $7$ is quite easy, we directly compute $2 \times 7 = 14$. However, since we are talking about fixed point arithmetic, we need to process $2$ and $7$ into fixed point format before performing the multiplication. First, we convert these numbers into a fixed point representation by multiplying them with the scaling factor $2^{64}$. In this case, $2$ becomes $2 \times 2^{64}$ and $7$ becomes $7 \times 2^{64}$. These converted numbers are now in a format that allows for integer-based calculations while simulating floating-point precision. | ||
|
||
Next, we perform the multiplication. In fixed point arithmetic, when we multiply two numbers, the result's scale is the square of the original scale. So, when we multiply the fixed point representations of $2$ and $7$, the calculation is equivalent to $(2 \times 2^{64}) \times (7 \times 2^{64})$. This results in a number that is scaled by $(2^{64})^2$. | ||
|
||
However, we want our final answer to be in the same scale as our original inputs, which is $2^{64}$. To achieve this, we divide our result by the scaling factor $2^{64}$. This step readjusts the scale of the result back to our intended scale. The final computation is therefore $((2 \times 2^{64}) \times (7 \times 2^{64})) / 2^{64}$, which gives us the correctly scaled result of $2.5$ in fixed point format. | ||
|
||
By leveraging our implementation, you can simply do the above procedure in Tact Language: | ||
|
||
```js | ||
import "./packages/math/float.fc"; | ||
|
||
@name(safeMul) | ||
extends native safeMul(self: Int, b: Int): Int; | ||
|
||
contract MathExample with Deployable { | ||
x: Int = 2; | ||
y: Int = 7; | ||
|
||
get fun safeMul(): Int { | ||
let a: Int = self.x.toFloat(); | ||
let b: Int = self.y.toFloat(); | ||
return a.safeMul(b); | ||
} | ||
} | ||
``` | ||
|
||
### Division | ||
|
||
Division in fixed point arithmetic follows a logic similar to multiplication, but with a few differences to accommodate the nature of division. Using the same numbers $2$, $7$, and scaling factor $2^{64}$ as in the multiplication example, let's break down the process of division. | ||
|
||
First, like in multiplication, we convert our numbers into fixed point format using the scaling factor $2^{64}$. So, $2$ becomes $2 \times 2^{64}$ and $7$ becomes $7 \times 2^{64}$. These numbers are now ready for arithmetic operations in fixed point format. | ||
|
||
When performing division in fixed point arithmetic, it's important to maintain the scale of the result consistent with the scale of the inputs. To divide $2$ by $7$ in fixed point format, we calculate $(2 \times 2^{64}) / (7 \times 2^{64})$. Here, the scaling factors in the numerator and denominator cancel each other out. This leaves us with the division of the original numbers, which is $2 / 7 = 0$. | ||
|
||
However, this direct division would lead to a loss of precision since $floor(2 / 7) = 0$. To address this, we can multiply the numerator by an additional scaling factor before performing the division, and divide it at the end of computation. This means we calculate $((2 \times 2^{64}) \times 2^{64}) / (7 \times 2^{64}) / 2^{64}$. Now, the result of this division will align with the scale of our inputs. | ||
|
||
In Tact Language, this division process can be implemented as follows: | ||
|
||
```js | ||
import "./packages/math/float.fc"; | ||
|
||
@name(safeDiv) | ||
extends native safeDiv(self: Int, b: Int): Int; | ||
|
||
contract MathExample with Deployable { | ||
x: Int = 2; | ||
y: Int = 7; | ||
|
||
get fun safeDiv(): Int { | ||
let a: Int = self.x.toFloat(); | ||
let b: Int = self.y.toFloat(); | ||
return a.safeDiv(b); | ||
} | ||
} | ||
``` |
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,7 @@ | ||
{ | ||
"label": "Tutorial - Math", | ||
"position": 1, | ||
"link": { | ||
"type": "generated-index" | ||
} | ||
} |
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 |
---|---|---|
|
@@ -3,6 +3,8 @@ | |
|
||
const lightCodeTheme = require("prism-react-renderer/themes/github"); | ||
const darkCodeTheme = require("prism-react-renderer/themes/dracula"); | ||
const math = require('remark-math'); | ||
const katex = require('rehype-katex'); | ||
|
||
/** @type {import('@docusaurus/types').Config} */ | ||
const config = { | ||
|
@@ -42,6 +44,8 @@ const config = { | |
// Please change this to your repo. | ||
// Remove this to remove the "edit this page" links. | ||
editUrl: "https://github.com/Ton-Dynasty/tondynasty-contracts/pulls", | ||
remarkPlugins: [math], | ||
rehypePlugins: [katex], | ||
}, | ||
blog: { | ||
showReadingTime: true, | ||
|
@@ -56,6 +60,16 @@ const config = { | |
], | ||
], | ||
|
||
stylesheets: [ | ||
{ | ||
href: 'https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css', | ||
type: 'text/css', | ||
integrity: | ||
'sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM', | ||
crossorigin: 'anonymous', | ||
}, | ||
], | ||
|
||
themeConfig: | ||
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */ | ||
({ | ||
|
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 |
---|---|---|
|
@@ -2109,6 +2109,11 @@ | |
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.13.tgz#02c24f4363176d2d18fc8b70b9f3c54aba178a85" | ||
integrity sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ== | ||
|
||
"@types/katex@^0.11.0": | ||
version "0.11.1" | ||
resolved "https://registry.yarnpkg.com/@types/katex/-/katex-0.11.1.tgz#34de04477dcf79e2ef6c8d23b41a3d81f9ebeaf5" | ||
integrity sha512-DUlIj2nk0YnJdlWgsFuVKcX27MLW0KbKmGVoUHmFr+74FYYNUDAaj9ZqTADvsbE8rfxuVmSFc7KczYn5Y09ozg== | ||
|
||
"@types/mdast@^3.0.0": | ||
version "3.0.13" | ||
resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.13.tgz#b7ba6e52d0faeb9c493e32c205f3831022be4e1b" | ||
|
@@ -3067,7 +3072,7 @@ commander@^7.2.0: | |
resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" | ||
integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== | ||
|
||
commander@^8.3.0: | ||
commander@^8.0.0, commander@^8.3.0: | ||
version "8.3.0" | ||
resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" | ||
integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== | ||
|
@@ -4319,6 +4324,11 @@ hast-util-from-parse5@^6.0.0: | |
vfile-location "^3.2.0" | ||
web-namespaces "^1.0.0" | ||
|
||
[email protected], hast-util-is-element@^1.0.0: | ||
version "1.1.0" | ||
resolved "https://registry.yarnpkg.com/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz#3b3ed5159a2707c6137b48637fbfe068e175a425" | ||
integrity sha512-oUmNua0bFbdrD/ELDSSEadRVtWZOf3iF6Lbv81naqsIV99RnSCieTbWuWCY8BAeEfKJTKl0gRdokv+dELutHGQ== | ||
|
||
hast-util-parse-selector@^2.0.0: | ||
version "2.2.5" | ||
resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz#d57c23f4da16ae3c63b3b6ca4616683313499c3a" | ||
|
@@ -4351,6 +4361,15 @@ hast-util-to-parse5@^6.0.0: | |
xtend "^4.0.0" | ||
zwitch "^1.0.0" | ||
|
||
hast-util-to-text@^2.0.0: | ||
version "2.0.1" | ||
resolved "https://registry.yarnpkg.com/hast-util-to-text/-/hast-util-to-text-2.0.1.tgz#04f2e065642a0edb08341976084aa217624a0f8b" | ||
integrity sha512-8nsgCARfs6VkwH2jJU9b8LNTuR4700na+0h3PqCaEk4MAnMDeu5P0tP8mjk9LLNGxIeQRLbiDbZVw6rku+pYsQ== | ||
dependencies: | ||
hast-util-is-element "^1.0.0" | ||
repeat-string "^1.0.0" | ||
unist-util-find-after "^3.0.0" | ||
|
||
hastscript@^6.0.0: | ||
version "6.0.0" | ||
resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640" | ||
|
@@ -4942,6 +4961,13 @@ jsonfile@^6.0.1: | |
optionalDependencies: | ||
graceful-fs "^4.1.6" | ||
|
||
katex@^0.13.0: | ||
version "0.13.24" | ||
resolved "https://registry.yarnpkg.com/katex/-/katex-0.13.24.tgz#fe55455eb455698cb24b911a353d16a3c855d905" | ||
integrity sha512-jZxYuKCma3VS5UuxOx/rFV1QyGSl3Uy/i0kTJF3HgQ5xMinCQVF8Zd4bMY/9aI9b9A2pjIBOsjSSm68ykTAr8w== | ||
dependencies: | ||
commander "^8.0.0" | ||
|
||
keyv@^3.0.0: | ||
version "3.1.0" | ||
resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" | ||
|
@@ -6388,6 +6414,26 @@ regjsparser@^0.9.1: | |
dependencies: | ||
jsesc "~0.5.0" | ||
|
||
rehype-katex@5: | ||
version "5.0.0" | ||
resolved "https://registry.yarnpkg.com/rehype-katex/-/rehype-katex-5.0.0.tgz#b556f24fde918f28ba1cb642ea71c7e82f3373d7" | ||
integrity sha512-ksSuEKCql/IiIadOHiKRMjypva9BLhuwQNascMqaoGLDVd0k2NlE2wMvgZ3rpItzRKCd6vs8s7MFbb8pcR0AEg== | ||
dependencies: | ||
"@types/katex" "^0.11.0" | ||
hast-util-to-text "^2.0.0" | ||
katex "^0.13.0" | ||
rehype-parse "^7.0.0" | ||
unified "^9.0.0" | ||
unist-util-visit "^2.0.0" | ||
|
||
rehype-parse@^7.0.0: | ||
version "7.0.1" | ||
resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-7.0.1.tgz#58900f6702b56767814afc2a9efa2d42b1c90c57" | ||
integrity sha512-fOiR9a9xH+Le19i4fGzIEowAbwG7idy2Jzs4mOrFWBSJ0sNUgy0ev871dwWnbOo371SjgjG4pwzrbgSVrKxecw== | ||
dependencies: | ||
hast-util-from-parse5 "^6.0.0" | ||
parse5 "^6.0.0" | ||
|
||
relateurl@^0.2.7: | ||
version "0.2.7" | ||
resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" | ||
|
@@ -6407,6 +6453,11 @@ [email protected]: | |
resolved "https://registry.yarnpkg.com/remark-footnotes/-/remark-footnotes-2.0.0.tgz#9001c4c2ffebba55695d2dd80ffb8b82f7e6303f" | ||
integrity sha512-3Clt8ZMH75Ayjp9q4CorNeyjwIxHFcTkaektplKGl2A1jNGEUey8cKL0ZC5vJwfcD5GFGsNLImLG/NGzWIzoMQ== | ||
|
||
remark-math@3: | ||
version "3.0.1" | ||
resolved "https://registry.yarnpkg.com/remark-math/-/remark-math-3.0.1.tgz#85a02a15b15cad34b89a27244d4887b3a95185bb" | ||
integrity sha512-epT77R/HK0x7NqrWHdSV75uNLwn8g9qTyMqCRCDujL0vj/6T6+yhdrR7mjELWtkse+Fw02kijAaBuVcHBor1+Q== | ||
|
||
[email protected]: | ||
version "1.6.22" | ||
resolved "https://registry.yarnpkg.com/remark-mdx/-/remark-mdx-1.6.22.tgz#06a8dab07dcfdd57f3373af7f86bd0e992108bbd" | ||
|
@@ -6461,7 +6512,7 @@ renderkid@^3.0.0: | |
lodash "^4.17.21" | ||
strip-ansi "^6.0.1" | ||
|
||
repeat-string@^1.5.4: | ||
repeat-string@^1.0.0, repeat-string@^1.5.4: | ||
version "1.6.1" | ||
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" | ||
integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== | ||
|
@@ -7241,7 +7292,7 @@ [email protected]: | |
trough "^1.0.0" | ||
vfile "^4.0.0" | ||
|
||
unified@^9.2.2: | ||
unified@^9.0.0, unified@^9.2.2: | ||
version "9.2.2" | ||
resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.2.tgz#67649a1abfc3ab85d2969502902775eb03146975" | ||
integrity sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ== | ||
|
@@ -7265,6 +7316,13 @@ [email protected], unist-builder@^2.0.0: | |
resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-2.0.3.tgz#77648711b5d86af0942f334397a33c5e91516436" | ||
integrity sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw== | ||
|
||
unist-util-find-after@^3.0.0: | ||
version "3.0.0" | ||
resolved "https://registry.yarnpkg.com/unist-util-find-after/-/unist-util-find-after-3.0.0.tgz#5c65fcebf64d4f8f496db46fa8fd0fbf354b43e6" | ||
integrity sha512-ojlBqfsBftYXExNu3+hHLfJQ/X1jYY/9vdm4yZWjIbf0VuWF6CRufci1ZyoD/wV2TYMKxXUoNuoqwy+CkgzAiQ== | ||
dependencies: | ||
unist-util-is "^4.0.0" | ||
|
||
unist-util-generated@^1.0.0: | ||
version "1.1.6" | ||
resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.6.tgz#5ab51f689e2992a472beb1b35f2ce7ff2f324d4b" | ||
|