diff --git a/README.md b/README.md
index 88eed0b..dcd5d59 100644
--- a/README.md
+++ b/README.md
@@ -9,6 +9,7 @@ The [src](src) directory provides a list of lessons with exercises and solutions
1.
* [Hello World!](src/1.Hello_World/HelloWorld.md)
+ * [Financial Math: `FixedPointNumber` class.](src/1.Hello_World/FinancialMath.md)
2.
* [The Bloom filter.](src/2.Bloom_Filter/BloomPart1.md)
* [The Bloom filter: advanced topics on `k` and `m` parameters.](src/2.Bloom_Filter/BloomPart2.md)
diff --git a/package.json b/package.json
index 245c85d..089a666 100644
--- a/package.json
+++ b/package.json
@@ -18,7 +18,7 @@
"license": "MIT",
"description": "VeChain SDK Tutorial for NodeJS.",
"dependencies": {
- "@vechain/sdk-network": "1.0.0-rc.1",
+ "@vechain/sdk-core": "1.0.0-rc.1",
"bignumber.js": "^9.1.1"
},
"devDependencies": {
diff --git a/src/1.Hello_World/FinancialMath.md b/src/1.Hello_World/FinancialMath.md
index b101966..0271ae5 100644
--- a/src/1.Hello_World/FinancialMath.md
+++ b/src/1.Hello_World/FinancialMath.md
@@ -2,16 +2,502 @@
# Financial Math
-JavaScript (JS) was designed as front-end language.
+JavaScript (JS) was designed as front-end language, providing the simpler data type to cope with the need
+of rendering, initially just the `string` type to express texts and `number` or `bigint` types to compute math.
+JS was not designed to be strongly typed language, but the language was designed to delegate at runtime
+the assessment of the type to represent any variable according its content.
+When the success of JS as 'browser language' made it popular as a more general purpose language,
+the need to pinpoint the data type of variable pushed the creation of TypeScript (TS)
+as a language derived by and compatible with JS. TS makes explicit the type definition of variables.
-The JS `number` type implements the 64 bits [Double Precision Floating Point](https://en.wikipedia.org/wiki/Double-precision_floating-point_format)
-representation as the `double` type common in *C#*, *Java?Kotlin* and *Rust/Zig* programming languages.
-This representation approximates the real value with less precision as the value moves to the edge of
-the information can be represented in 8 bytes,
+## Number Type Limits
-String doesn't oblige to approximation.
+The JS `number` type implements the 64
+bits [Double Precision Floating Point](https://en.wikipedia.org/wiki/Double-precision_floating-point_format)
+representation as the `double` type common in *C#*, *Java/Kotlin* and *Rust/Zig* programming languages.
+This representation uses 8 bytes to approximate the value as follows
+- 1 bit to represent the value **sign**,
+- 11 bits to represent an **exponent**, one bit for the exponent sign and 210 = 0-1024 as exponent range
+ value,
+- 52 bits to represent an integer - named **significand** multiplied for the above **exponent** and **sign**,
+ 252 is roughly equal to 4500000000000000 (45 followed by fourteen zeros).
+Any value can't be represented exactly as a product of the integers **significand** × **2exponent**
+× **sign** is approximated with less precision for values very big or very small fraction, positive or negative doesn't
+matter.
-https://mikemcl.github.io/bignumber.js/
+Actually, IEEE-754 represents precisely values in the range ±2.23×10−308 to ±1.80×10308 in 16
+decimal digits comprehensive of the integer and fractional parts.
+It's important to anticipate that, due to the finite quantity of computer memory and the binary nature of electronic
+logic, computers can only represent values as polynomial expressions of powers of 2. Hence, any rational value not the
+result of a ratio between two values made of powers of two, like **1/3** returning "zero dot an infinite string of
+three" (also named '[repeating decimal](https://en.wikipedia.org/wiki/Repeating_decimal) three'), they
+can only be approximated. The quantity of memory to represent precisely 1/3 is infinite.
+It is worth to remember any [irrational number](https://en.wikipedia.org/wiki/Irrational_number),
+$\sqrt{2}$ and π are the most famous, can be only approximated in a computer architecture
+because writing an irrational value needs an infinite number of digits.
+
+From what explained above, albeit the IEEE-754 allows to express a wide range of values, the 16 decimal digit
+precision is not sufficient for many purposes, like financial math. For example, approximating values to cents (two
+digits), the biggest value representable in any currency is 1014 hence at most 10 trillions (1012)
+of the currency units. Using more digits to represent fraction of cents to compute the
+[compound interest](https://en.wikipedia.org/wiki/Compound_interest), the remaining digits allow to express
+values in the range of billions, this is a too small range.
+
+## Cryptocurrency Economy Math
+
+Cryptocurrencies like [BTC](https://en.wikipedia.org/wiki/Bitcoin), [ETH](https://en.wikipedia.org/wiki/Ethereum) or
+VeChain [VET](https://docs.vechain.org/introduction-to-vechain/dual-token-economic-model/vechain-vet) requires
+18 decimal digits to express the fractional part of their nomination currency unit, plus the digits required to
+express the units, hence the IEEE-754 precision is too coarse for the purpose of cryptocurrency economy.
+
+The need of 18 digits for the fractional part of a cryptocurrency is suggested by the idea to express
+cryptocurrency values as an integer value of its atomic smallest subunit named **wei**,
+to honor the computer engineer [Wei Dai](https://en.wikipedia.org/wiki/Wei_Dai).
+
+JS provides the
+[`bigint`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt)
+type, characterized to be a variable length type,
+as [`string`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) is.
+The `bigint` type expands to include all the bits needed to express any integer value,
+`bigint` values are limited by available memory of the JS runtime.
+However, if `bigint` is ideal to express currency values, it doesn't work well for any mathematics operation
+involving the concept of ratio, as the division and root. Between integers, 1/3=0, not ideal when the same
+result computed between real values returns 'repeating decimal' .3.
+
+## FixedPointNumber Type
+
+The VeChain SDK provides the `FixedPointNumber` class to provide an unrestricted representation of values,
+as `bigint` but supporting the concept of 'ratio' and rational numbers, allowing to define the precision
+of the approximation of irrational values.
+
+The most important characteristic of the `FixedPointNumber` class is the algorithms it provides are purely based
+on `bigint` hence the code developed using the SDK runs smoothly on any JS runtime because `bigint` type is
+a base type of the JS language.
+
+### bignumber.js comparison
+
+In JS there are other libraries addressing the same problem to represent values with adjustable precision.
+Among them, it is worth to name [**bignumber.js**](https://mikemcl.github.io/bignumber.js/).
+The `FixedPointNumber` class was developed using **bignumber.js** as reference and benchmark:
+most of the methods provided by the `FixedPointNumber` class have the same names and signature
+of the same methods provided by **bignumber.js**. Being **bignumber.js** a popular and excellent library
+to deal with financial math in JS, `FixedPointNumber` class is designed to make trivial to adapt code
+developed for **bignumber.js** to run based on `FixedPointNumber`.
+
+The reason the VeChain SDK provides its `FixedPointNumber` class instead of using **bignumber.js** is because
+the algorithms implemented in the class allows a true unrestricted precision, just limited by the available memory,
+those are simpler to verify manually, the source code links the abstract descriptions in math literature hence
+everyone competent can verify those are correctly implemented for each non-trivial algorithm like the division,
+the power exponentiation and square roots. All algorithms are strictly based on `bigint`.
+
+The two libraries differ in the way they represent values.
+
+The **bignumber.js** library encodes each value
+similarly as IEEE-754 `number` using **significand**, **exponent** and **sign** properties, with the difference
+the **significand** is an array of `numbers` (8 bytes per element) encoding each digit of the value to approximate.
+For example, the value -1.234567 × 104 is represented internally as
+
+- **significand** = `[1,2,3,4,5,6,7]`
+- **exponent** = `4`
+- **sign** = `1` (to flag a negative value).
+
+The mention and comparison with **bignumber.js** is due because `FixedPointNumber` class doesn't implement
+the whole functionalities of the **bignumber.js** library. For example `FixedPointNumber` class supports
+the square root operation, but it doesn't support yet the power to fractional exponent (n0.5/sup> = $\sqrt{n}$).
+
+**_NOTE:_** VeChain uses and suggests to use [**bignumber.js**](https://mikemcl.github.io/bignumber.js/)
+for the functionalities not included in the `FixedPointNumber` class. The **bignumber.js** library
+is not part of the SDK and must be imported explicitly in any JS/TS project using it.
+
+### FixedPointNumber math
+
+The `FixedPointNumber` class adopts a much simpler implementation inspired to the way the blockchain protocols,
+like Bitcoin, Ethereum and Thor represents cryptocurrencies values.
+
+- If the value is an integer, it's represented in a `bigint`.
+- If the value is a rational value, hence it has a fractional part between ±1 and 0, it is scaled up multiplying itself
+ by 10 for the number of times equal to the number of digits required to write the fractional part.
+
+For this reason the `FixedPointNumber` exposes two properties, both of `bigint` type:
+
+- `scaledValue` expresses the original value
+ - if integer the integer itself,
+ - if not integer the value multiplied by 10`fractionalDigits`;
+- `fractionalDigit` expresses the number of decimal digits required to write the fractional part of the value, it's `0`
+ for integers.
+
+For example 1.234567 is encoded as
+
+- `scaledvalue = 1234567` (as 1.234567 × 106),
+- `fractionalDigit = 6`.
+
+The expression 'fixed point number' means a `FixedPointNumber` objects uses `fractionalDigit` to fix its
+precision and pinpoint where the decimal separator, (the `.` dot character by default) is placed when the value
+is printed.
+
+## FixedPointNumber In Action
+
+The `FixedPointNumber` class is part of the VeChain Data Model** hence, the .`of(exp: bigint | number | string)`
+method is the standard way to create a new object from the `exp` argument.
+
+The following example shows the same value, represented by two different type expressions, creates two equivalent
+objects and how the `.bi` and `.n` properties behave.
+
+```typescript
+// STEP 1: import FixedPointNumber and BigNumber to compare results among the two libraries.
+import {FixedPointNumber} from '@vechain/sdk-core';
+import {BigNumber} from 'bignumber.js';
+
+// STEP 2: create two equivalent objects from different expression types and check they are equivalent.
+let x = FixedPointNumber.of(123.456789);
+let y = FixedPointNumber.of('123.456789');
+console.log(`FPN value ${x} from number is ${x.isEqual(y) ? '' : 'not'}equal to ${y} from string.`);
+
+// STEP 3: cast to a number
+console.log(`Cast FPN value to number is ${x.n}.`);
+
+// STEP 4: cast a rational value to a bigint type truncates the value to integer.
+console.log(`Cast FPN value to bigint is ${x.bi}.`);
+```
+
+### Division challenge
+
+The arithmetic of the `FixedPointNumber` class is trivial for addition, subtraction and multiplication, the game
+becomes interesting when the division is involved. Recalling the well known ratio 1/3, the result of the division
+between `bigint` is zero and from above explanation, we know the object represents the internal operand as integers.
+How `FixedPointNumber` class solves the challenge to get a rational result from integer division?
+
+The `FixedPointNumber` class uses the `fractionalDigits` property to scale up and down the `scaledValue`
+appropriately to a precision fine enough, by default when integers are involved in the division, logarithm and root
+operations internally, the class' algorithms scale up the value representation of 1020
+imposing an internal minimal precision of 20 decimal digits,
+to be sure the result is accurate for the 18 digits the cryptocurrency math needs to represent any
+value in terms of **wei** atomic subunits, have two spare digits more to approximate the less significant **wei** digit.
+
+We will see later the `.dp(decimalPlaces: bigint | number)` method allows to fix the minimal required precision.
+When two rational numbers are involved in arithmetic operations risking leading to a loss of precision,
+the internal math is scaled up to the double of the fractional digits of argument having the higher
+`fractionalDigit` value using the `.dp` method.
+
+For the 1/3 ratio the division is made between
+10000000000000000000000000000000000000000 / 30000000000000000000000000000000000000000,
+hence the integer is scaled up by 10default 20 fractional digit precision multiplied 2 times:
+the division will return something like 0.33333333333333333333????????????????????
+where the question mark acts as a placeholder for digits should be 3, but it will diverge from 3 as the digit is closer
+to the less meaningful digit. As recalled many times, computers must approximate at some point.
+Then, the 40 digits internal precision is scaled down 10default 20 fractional digit preserving
+an accurate results for the wished 20 fractional digits' precision.
+
+The elegance of `FixedPointNumber` implementation is the precision is fixed, but expand and shrink internally to
+assure at least the wished precision, consuming more memory only during the computation, returning to the
+operating system after the result is computed, in any case consuming less memory than **bignumber.js**
+implementation, the latter uses 8 bytes per each digit of precision.
+
+The following example divide 1 by 3 comparing three results made by JS numbers, **bignumber.js** math and
+`FixedPointNumber` math with the default precision of 20 fractional digits.
+
+```typescript
+// STEP 5: compute 1/3 comparing JS number, BigNumber and SDK FixedPointNumber math
+x = FixedPointNumber.of(1);
+y = FixedPointNumber.of(3);
+let r = x.div(y); // r for 'ratio'.
+console.log(`${x}/${y} => JS = ${x.n / y.n};\tBigNumber = ${BigNumber(x.n).div(y.n)};\tSDK = ${r}`);
+```
+
+For sake of comprehension, the snipped above prints
+
+```text
+1/3 => JS = 0.33333333333333326; BigNumber = 0.33333333333333328889; SDK = 0.33333333333333333333
+```
+
+As expected JS `number` type math is precise in 16 digits included the integer `0` and the following fifteen `3`, then
+it diverges.
+
+The **bignumber.js** math returns a 20 fractional digits ratio more precise than JS math but approximate for the last 4
+digits.
+It's a good practice using **bignumber.js** to set a decimal precision, calling the same
+`.dp(decimalPlaces: bigint | number)` method in common with the `FixedPointNumber` class, to a number of digits greater
+than the minimal needed, then discard the last ones where precision diverge. For example, needing at least 20 decimal
+precision, set `.dp(25)` and discard the last five digits.
+
+The SDK math returns the value closer to the theoretical real number ratio.
+
+Let's see what happen when we increase the precision to 80 fractional digits.
+
+```typescript
+// STEP 6: increase the precision to 80 decimal digits.
+let fd = 80; // Fractional Digits.
+x = x.dp(80); // Force x to fd precision, .div function will adapt y automatically
+r = x.div(y); // Ratio
+let a = BigNumber(x.n).dp(fd); // Force to fd precision.
+let b = BigNumber(y.n).dp(fd); // Force to fd precision
+let q = a.div(b) // q for 'quotient' synonymous of 'ratio'.
+console.log(`${x}/${y} => BigNumber ${q};\t SDK = ${r}`);
+```
+
+The code prints
+
+```text
+1/3 => BigNumber 0.33333333333333328889; SDK = 0.33333333333333333333333333333333333333333333333333333333333333333333333333333333
+```
+
+because **bignumber.js** approximation algorithm converge to 0.33333333333333328889 followed by not meaningful zeros.
+The `FixedPointNumber` is more accurate regarding divisions.
+
+### Square root challenge
+
+The next example computes the square root of few natural numbers, let's see how JS, **bignumber.js** and
+`FixedPointNumber` class behave.
+
+```typescript
+// STEP 7: compute the squared root of the natural number from 0 to n.
+fd = 20;
+let n = 8
+let rows = [];
+for (let i = 0; i <= n; i++) {
+ x = FixedPointNumber.of(i).dp(fd).sqrt();
+ a = BigNumber(i).dp(fd).sqrt();
+ rows.push({
+ 'JS number': Math.sqrt(i),
+ 'BigNumber': `${a}`,
+ 'SDK FixedPointNumber': `${x}`
+ })
+}
+console.table(rows);
+```
+
+The code prints the table
+
+```text
+┌─────────┬────────────────────┬──────────────────────────┬──────────────────────────┐
+│ (index) │ JS number │ BigNumber │ SDK FixedPointNumber │
+├─────────┼────────────────────┼──────────────────────────┼──────────────────────────┤
+│ 0 │ 0 │ '0' │ '0' │
+│ 1 │ 1 │ '1' │ '1' │
+│ 2 │ 1.4142135623730951 │ '1.4142135623730950488' │ '1.4142135623730950488' │
+│ 3 │ 1.7320508075688772 │ '1.73205080756887729353' │ '1.73205080756887729352' │
+│ 4 │ 2 │ '2' │ '2' │
+│ 5 │ 2.23606797749979 │ '2.23606797749978969641' │ '2.2360679774997896964' │
+│ 6 │ 2.449489742783178 │ '2.4494897427831780982' │ '2.44948974278317809819' │
+│ 7 │ 2.6457513110645907 │ '2.6457513110645905905' │ '2.6457513110645905905' │
+│ 8 │ 2.8284271247461903 │ '2.8284271247461900976' │ '2.8284271247461900976' │
+└─────────┴────────────────────┴──────────────────────────┴──────────────────────────┘
+```
+
+where the divergence between **bignumber.js** and the `FixedPointNumber` is limited to the last less significant digit.
+
+Once more, is worth to repeat there is not an always ideal way to approximate real numbers to the binary representation
+computers provide, it's worth to repeat the previous experiment forcing the precision to 80 fractional digits, once more
+**bignumber.js** converges to a result having less digits, `FixedPointNumber` math keep computing until the 80
+th digit, internally resolving the computation with 160 digits.
+
+The code
+
+```typescript
+// STEP 8: compute the squared root of the natural number from 0 to n.
+fd = 80;
+n = 8
+rows = [];
+for (let i = 0; i <= n; i++) {
+ x = FixedPointNumber.of(i).dp(fd).sqrt();
+ a = BigNumber(i).dp(fd).sqrt();
+ rows.push({
+ 'JS number': Math.sqrt(i),
+ 'BigNumber': `${a}`,
+ 'SDK FixedPointNumber': `${x}`
+ })
+}
+console.table(rows);
+```
+
+prints
+
+```text
+┌─────────┬────────────────────┬──────────────────────────┬──────────────────────────────────────────────────────────────────────────────────────┐
+│ (index) │ JS number │ BigNumber │ SDK FixedPointNumber │
+├─────────┼────────────────────┼──────────────────────────┼──────────────────────────────────────────────────────────────────────────────────────┤
+│ 0 │ 0 │ '0' │ '0' │
+│ 1 │ 1 │ '1' │ '1' │
+│ 2 │ 1.4142135623730951 │ '1.4142135623730950488' │ '1.41421356237309504880168872420969807856967187537694807317667973799073247846210703' │
+│ 3 │ 1.7320508075688772 │ '1.73205080756887729353' │ '1.73205080756887729352744634150587236694280525381038062805580697945193301690880003' │
+│ 4 │ 2 │ '2' │ '2' │
+│ 5 │ 2.23606797749979 │ '2.23606797749978969641' │ '2.23606797749978969640917366873127623544061835961152572427089724541052092563780489' │
+│ 6 │ 2.449489742783178 │ '2.4494897427831780982' │ '2.44948974278317809819728407470589139196594748065667012843269256725096037745731502' │
+│ 7 │ 2.6457513110645907 │ '2.6457513110645905905' │ '2.64575131106459059050161575363926042571025918308245018036833445920106882323028362' │
+│ 8 │ 2.8284271247461903 │ '2.8284271247461900976' │ '2.82842712474619009760337744841939615713934375075389614635335947598146495692421407' │
+└─────────┴────────────────────┴──────────────────────────┴──────────────────────────────────────────────────────────────────────────────────────┘
+```
+
+Note if you manually round the long SDK results to the digits printed in the **bignumber.js** result, you will get the
+**bignumber.js** results.
+The two libraries approximate the theoretical real number results consistently but `FixedPointNumber` works
+with higher precision when instructed to do because it was designed to respect at least the 20 digits of fractional
+precision cryptocurrency math requires.
+
+### Limit challenge
+
+The `FixedPointNumber` class works as the JS `number` does to approximate the results at the limits.
+The following examples computes the most classic limits of the division, by zero, by infinity and between zero
+arguments.
+
+```typescript
+// START-SNIPPET: FinancialMath_5
+// STEP 9: compute the divisions by zero, infinity and between zeros.
+r = x.div(FixedPointNumber.ZERO);
+console.log(`${x}/0 = ${r}`);
+r = x.div(FixedPointNumber.of(Infinity));
+console.log(`${x}/Infinity = ${r}`);
+r = x.div(FixedPointNumber.ZERO.div(FixedPointNumber.ZERO));
+console.log(`0/0 = ${r}`);
+```
+
+Whatever is the last value of `x`, the code prints
+
+```text
+2.82842712474619009760337744841939615713934375075389614635335947598146495692421407/0 = Infinity
+2.82842712474619009760337744841939615713934375075389614635335947598146495692421407/Infinity = 0
+0/0 = NaN
+```
+
+as expected.
+
+### Compound Interest challenge
+
+The [Compount Interest](https://en.wikipedia.org/wiki/Compound_interest)
+is the result of reinvesting or retaining interest that would otherwise be paid out from a capital,
+or of the accumulation of debts from a borrower.
+
+From the referred literature the formula to compute the
+
+- *A*: accrued amount, from the
+- *P* := principal capital, at the
+- *r* := [nominal annual interest rate](https://en.wikipedia.org/wiki/Nominal_interest_rate), when accrued
+- *n* := times per
+- *t* := number of years in decimal form, hence 6 month = 0.5
+
+is the following expression.
+
+$$A=P(1+{r \over n})^{nt}$$
+
+The following snipped shows how to implement the above formula with the `FixedPointNumber` class
+for the simpler case of 10,000 currency units invested at 15% of interest rate annually.
+
+```typescript
+// STEP 10: compute the simple interest reat for 10,000 currency unit at 15% for one year
+let P = 10000; // 10,000 $
+let R = 0.15; // 15% interest rate
+let N = 1; // interest accrued times per year
+let T = 1; // 1 year of investment time
+let jsA = interestWithNumberType(P, R, N, T);
+console.log(
+ `JS number => ${P} at ${R} accrued ${N} per year for ${T} years = ${jsA} `
+);
+let bnA = interestWithBigNumberType(P, R, N, T);
+console.log(
+ `BigNumber => ${P} at ${R} accrued ${N} per year for ${T} years = ${bnA} `
+);
+let fpA = interestWithFixedPointNumberType(P, R, N, T);
+console.log(
+ `SDK FixedPointNumber => ${P} at ${R} accrued ${N} per year for ${T} years = ${fpA} `
+);
+
+```
+
+The above code prints
+
+```text
+JS number => 10000 at 0.15 accrued 1 per year for 1 years = 11500
+BigNumber => 10000 at 0.15 accrued 1 per year for 1 years = 11500
+SDK FixedPointNumber => 10000 at 0.15 accrued 1 per year for 1 years = 11500
+```
+
+where the math is simple.
+
+It becomes interesting to understand if we could have accrued in the capital the interests once per day,
+the code becomes
+
+```typescript
+P = 10000; // 10,000 $
+R = 0.15; // 15% interest rate
+N = 365; // interest accrued times per day
+T = 1; // 1 year of investment time
+jsA = interestWithNumberType(P, R, N, T);
+console.log(
+ `JS number => ${P} at ${R} accrued ${N} per year for ${T} years = ${jsA} `
+);
+bnA = interestWithBigNumberType(P, R, N, T);
+console.log(
+ `BigNumber => ${P} at ${R} accrued ${N} per year for ${T} years = ${bnA} `
+);
+fpA = interestWithFixedPointNumberType(P, R, N, T);
+console.log(
+ `SDK FixedPointNumber => ${P} at ${R} accrued ${N} per year for ${T} years = ${fpA} `
+);
+```
+
+that prints the following output.
+
+```text
+JS number => 10000 at 0.15 accrued 365 per year for 1 years = 11617.984431282737
+BigNumber => 10000 at 0.15 accrued 365 per year for 1 years = 11617.984431282297580741332627901777130315693092582736415183243388318237491778342908385720809654240040970598789674377765947470867911564401090655498297277650975577399724748298427632216300469085882205126498872953842419903091295485650124501686949728680155745247474335138232482179528909255366536402392875329941467045245858869644197239128719066296683081367462543205390000804087922075544539860855742520269818193809495203557007634259996219745309932882459518798524968113901703633929888998635141912068168058452472183416934462187935057393732956042640561423418567082114578032214061928405512072912635929995221365892079381592086022940837672235708964650239008816227116838590877049591322964899152767454901676441240192497489253888772433181792034083619461274791847315352488935494000067256440171197925364612917886966149610377974675067875969329030185742031433985309342124192478167223066139006719604689359394196296969241000167807707526911942624844129728153376077127099662124501925926262400807908100667459068640705163071829628876166416144650604075464967358748105805082716622225378985664759817456721566584649980686571966739424426900555857787691088510512370790518609850265247504195307410003670920350652938085871229040577564845370642100134126774852650664481607739716900248270176440329598644103824418655594316501156008480980716682782242614278880139844472436437042938201287303745900970102452173445939781488072924165863076960481844351048526193390029595200330434638261284649942836277464922095624061067458197847435464948760326222404388856873196780809435008547776084396323890431631972013758894777140309741935129390297015768713582643582348068171065563802650256565960065201047582581116691865279018481443083634133404456871734224588349932851240939902278852857772240874090103073366139194999398085913528002041787949791674995548809236904350253066698952181458954491521587600763302070101055709667346467178274981943340531021522745779841173173100876264702725095018516677824199733818142804282300961031747257156885200868283262162552850804621026592584042666050361511605692823276578862937221646249263387226746019107252022914312737706377194312459934216793950004099882178225338416417778346328972245140417878899256520398132742852152375062744008410226501238905946472866254396245283539337213331252101745238242758925097416813000735388071657272215630320845974338897771656555041763973550598236914984192269963986648377816228129380629038592368286598983134185222188166799690901539746460579787203029749770287168278013060365079064355083674125148509306763746692482514248137552297251646678328412875814259875291593503972546227382158958840236846540788238035029805960355494051129276122800357236219110138260911217725961189217381637291618712318040507760126364551859509154428340741101957780412277285523094815506659402101296679158236819278380864803586590895640024979637785001490636069382753310067262080662008374551411237242197309339195940406115487850125037507130818294504053083257596428408392560703205549675447339493801368201043030474759039019262194914203062392087296343396390456485525267865121108385382592954860634880962986192817267439352666847666157489902571135514525578918745486509804822731475416985234489977625440493130772022775991189276290027329665587185531530543206454536574667659589367011127224587509531212717181754469270666867381661716929585894830103402709693499856666380325736846063373961108804197128223849684167133844214462156301412887963361227739403071660047619772673714272672989566030756704912026202806904414756141050877173820467126821863214589542154214507220674770172074480518122963953827143784132131825710319355839177131961519962164573936360504510921943071620721478225732241696092470545416711449091231197409947570800111816988728323993927748087694375103322002551786532908225959918071812885153862720547036040176234585041356183336408463671774717112402126019277392052386242595710299970836973058795919985261217215532463448040471027097475516349207504695405799630225500316467665530686280496720382451548335866755027079968901476069244547605637114883551093053617935204887355249377970202741626315706124691277605917831773229234758966829205297909455982503322015748307649778207164102031977513233675014015393778284541528252684639556356440622270627351404365171320231057321728478194017365783885424667313087866411074216194345063051555381054064172603323211738852864410237985108247729834346660957553062456473858762927866393100596426722935498446318146888420749640452411934666892103469174673382975989047523845717274521847403271371069986619972541545134253842186788375129293688126572862115387719324965105989737112901937915991076889355410549661930187265953467401303864531898460980266601723832501816138179044919871086722233148280249031510561730844340942342552752797339969515184261652305893177119221594180785248835404646836951992084403389209903064614958108955775017427938729861471896432889143754999514215866581787875780518195492324090030209238689898749847097547332201970042332361179187882205382279489123276038554324542376299699431748417940616697963498398453267693487839206000992468170890787809074465833833196463153840816879434824909726841353267661992302221702086547490035887290185256786019556867916403856180613548209407427428077370808423244926090002052378929146269431360111728923038525642285848635701334548272961940575527578214830306877087295496043094370029968461721725931122906959895776924708699238003938445300122852634182483059734712134447129574528252224219402082590956703689919029030659233330544907648740772169481354518754802501356274798096471385614129581771624648999966708748460996049922163688691654080111831302649842118325696763454547261669119872910738319187020169833406880898955868935770271402602941664640045686162116748081874962518451448492409874925161119248814895310170073897053291015297428406688653811585699741373977572356288036024901500826634896249641517953519216217122274853273198117378197515066390088275104495779954424594351352378367504170370879233091766599335920101029085831254897829565278260692483037266835050591587628531733520004295815824586141378604375739933891004253354434850469067291902679358555199320950619712947450075798438078077536095433962891948700437561843125672228886857921426124413819322261040245713801881593557146574769577389858802213472120864318927179303450317314525085067389652207907199919225422117470334759242721216889842249001301391538464988190653091063509157979978283643327678457770510881671899296170914332781679190799498034101397504720140904971144170292408274384079420894326525665371636278322421273278426258321203221354484372505412649801255887345653780015097250209794039905314799983216469415302328198528313913445705434316109137813061851157444468570986979549798365340231124713689691546533719643932708191712713553794071778556027123472573813780229986257007757249006153795993810131914431558015307058287798711665470068967296921977705979849136618985820319515622500964455777206091165624522977628174471858620757943222409585380288039284091830621551632490845848868973849571519283631765833497270062040941078383405528284681354175222701039860699557935839377689676090845746980725178910930934668502448387038652955220237816656950225719626759719896877157902206341245898584211319540483952858211899601220699880254374817804694710554521371836044904856003205531183610678081768092129075647044919307768538250858692323989632797219472711805573349208751209872914132180689485824
+SDK FixedPointNumber => 10000 at 0.15 accrued 365 per year for 1 years = 11617.9844312822975648
+```
+
+The output shows, if the approximation is acceptable, **bignumber.js** and `FixedPointNumber` class results are closer,
+but `FixedPointNumber` converge to a solution in the fraction digits, here 20 by default.
+
+From above, it is evident how much the compound interest formula is convenient for the lender (usually the bank) and not
+for the borrower.
+
+The two snippets above uses the following functions.
+
+```typescript
+// START-SNIPPET: FinancialMath_Functions
+// COMPOUND INTEREST FUNCTIONS FOR DIFFERENT DATA TYPES
+function interestWithBigNumberType(
+ P: number,
+ r: number,
+ n: number,
+ t: number
+): BigNumber {
+ const _P = BigNumber(P);
+ const _r = BigNumber(r);
+ const _n = BigNumber(n);
+ const _t = BigNumber(t);
+ return BigNumber(1).plus(_r.div(n)).pow(_t.times(_n)).times(_P);
+}
+
+function interestWithFixedPointNumberType(
+ P: number,
+ r: number,
+ n: number,
+ t: number
+): FixedPointNumber {
+ const _P = FixedPointNumber.of(P);
+ const _r = FixedPointNumber.of(r);
+ const _n = FixedPointNumber.of(n);
+ const _t = FixedPointNumber.of(t);
+ return FixedPointNumber.ONE.plus(_r.div(_n))
+ .pow(_t.times(_n))
+ .times(_P);
+}
+
+function interestWithNumberType(
+ P: number,
+ r: number,
+ n: number,
+ t: number
+): number {
+ return (1 + r / n) ** (t * n) * P;
+}
+```
+
+where you can play to adjust the precision in the `interestWithFixedPointNumberType` and `interestWithBigNumberType`
+functions, poking with the `.dp` method.
+
+You can verify math using a
+[compound interest calculator](https://www.investor.gov/financial-tools-calculators/calculators/compound-interest-calculator)
+online.
diff --git a/src/1.Hello_World/FinancialMath.ts b/src/1.Hello_World/FinancialMath.ts
index 74707bb..749f7dd 100644
--- a/src/1.Hello_World/FinancialMath.ts
+++ b/src/1.Hello_World/FinancialMath.ts
@@ -1,34 +1,149 @@
+// START-SNIPPET: FinancialMath_1
+// STEP 1: import FixedPointNumber and BigNumber to compare results among the two libraries.
import { FixedPointNumber } from '@vechain/sdk-core';
import { BigNumber } from 'bignumber.js';
+// STEP 2: create two equivalent objects from different expression types and check they are equivalent.
let x = FixedPointNumber.of(123.456789);
let y = FixedPointNumber.of('123.456789');
console.log(
`FPN value ${x} from number is ${x.isEqual(y) ? '' : 'not'}equal to ${y} from string.`
);
+
+// STEP 3: cast to a number
console.log(`Cast FPN value to number is ${x.n}.`);
+
+// STEP 4: cast a rational value to a bigint type truncates the value to integer.
console.log(`Cast FPN value to bigint is ${x.bi}.`);
+// END-SNIPPET: FinancialMath_1
+
+// START-SNIPPET: FinancialMath_2
+// STEP 5: compute 1/3 comparing JS number, BigNumber and SDK FixedPointNumber math
x = FixedPointNumber.of(1);
y = FixedPointNumber.of(3);
-let r = x.div(y);
+let r = x.div(y); // r for 'ratio'.
console.log(
- `FPN value = ${r}; JS value = ${x.n / y.n}; BigNumber value = ${BigNumber(x.n).div(y.n)}.`
+ `${x}/${y} => JS = ${x.n / y.n};\tBigNumber = ${BigNumber(x.n).div(y.n)};\tSDK = ${r}`
);
-x = x.dp(80); // must be updated
-r = x.div(y);
-console.log(`${r}`);
-
-const dp = 20;
-for (let n = 0; n <= 8; n++) {
- x = FixedPointNumber.of(n, BigInt(dp));
- r = x.sqrt();
- console.log(`${n}, ${r};\t${Math.sqrt(n)};\t${BigNumber(n).dp(dp).sqrt()}`);
+
+// END-SNIPPET: FinancialMath_2
+
+// START-SNIPPET: FinancialMath_3
+// STEP 6: increase the precision to 80 decimal digits.
+let fd = 80; // Fractional Digits.
+x = x.dp(80); // Force x to fd precision, .div function will adapt y automatically
+r = x.div(y); // Ratio
+let a = BigNumber(x.n).dp(fd); // Force to fd precision.
+const b = BigNumber(y.n).dp(fd); // Force to fd precision
+const q = a.div(b); // q for 'quotient' synonymous of 'ratio'.
+console.log(`${x}/${y} => BigNumber ${q};\t SDK = ${r}`);
+
+// END-SNIPPET: FinancialMath_3
+
+// START-SNIPPET: FinancialMath_3
+// STEP 7: compute the squared root of the natural number from 0 to n.
+fd = 20;
+let n = 8;
+let rows = [];
+for (let i = 0; i <= n; i++) {
+ x = FixedPointNumber.of(i).dp(fd).sqrt();
+ a = BigNumber(i).dp(fd).sqrt();
+ rows.push({
+ 'JS number': Math.sqrt(i),
+ BigNumber: `${a}`,
+ 'SDK FixedPointNumber': `${x}`
+ });
+}
+console.table(rows);
+
+// END-SNIPPET: FinancialMath_3
+
+// START-SNIPPET: FinancialMath_4
+// STEP 8: compute the squared root of the natural number from 0 to n.
+fd = 80;
+n = 8;
+rows = [];
+for (let i = 0; i <= n; i++) {
+ x = FixedPointNumber.of(i).dp(fd).sqrt();
+ a = BigNumber(i).dp(fd).sqrt();
+ rows.push({
+ 'JS number': Math.sqrt(i),
+ BigNumber: `${a}`,
+ 'SDK FixedPointNumber': `${x}`
+ });
+}
+console.table(rows);
+
+// END-SNIPPET: FinancialMath_4
+
+// START-SNIPPET: FinancialMath_5
+// STEP 9: compute the divisions by zero, infinity and between zeros.
+r = x.div(FixedPointNumber.ZERO);
+console.log(`${x}/0 = ${r}`);
+r = x.div(FixedPointNumber.of(Infinity));
+console.log(`${x}/Infinity = ${r}`);
+r = x.div(FixedPointNumber.ZERO.div(FixedPointNumber.ZERO));
+console.log(`0/0 = ${r}`);
+
+// END-SNIPPET: FinancialMath_5
+
+// START-SNIPPET: FinancialMath_6
+// STEP 10: compute the simple interest reat for 10,000 currency unit at 15% for one year
+const P = 10000; // 10,000 $
+const R = 0.15; // 15% interest rate
+const N = 1; // interest accrued times per year
+const T = 1; // 1 year of investment time
+const jsA = interestWithNumberType(P, R, N, T);
+console.log(
+ `JS number => ${P} at ${R} accrued ${N} per year for ${T} years = ${jsA} `
+);
+const bnA = interestWithBigNumberType(P, R, N, T);
+console.log(
+ `BigNumber => ${P} at ${R} accrued ${N} per year for ${T} years = ${bnA} `
+);
+const fpA = interestWithFixedPointNumberType(P, R, N, T);
+console.log(
+ `SDK FixedPointNumber => ${P} at ${R} accrued ${N} per year for ${T} years = ${fpA} `
+);
+
+// END-SNIPPET: FinancialMath_6
+
+// START-SNIPPET: FinancialMath_Functions
+// COMPOUND INTEREST FUNCTIONS FOR DIFFERENT DATA TYPES
+function interestWithBigNumberType(
+ P: number,
+ r: number,
+ n: number,
+ t: number
+): BigNumber {
+ const _P = BigNumber(P);
+ const _r = BigNumber(r);
+ const _n = BigNumber(n);
+ const _t = BigNumber(t);
+ return BigNumber(1).plus(_r.div(n)).pow(_t.times(_n)).times(_P);
+}
+
+function interestWithFixedPointNumberType(
+ P: number,
+ r: number,
+ n: number,
+ t: number
+): FixedPointNumber {
+ const _P = FixedPointNumber.of(P);
+ const _r = FixedPointNumber.of(r);
+ const _n = FixedPointNumber.of(n);
+ const _t = FixedPointNumber.of(t);
+ return FixedPointNumber.ONE.plus(_r.div(_n)).pow(_t.times(_n)).times(_P);
+}
+
+function interestWithNumberType(
+ P: number,
+ r: number,
+ n: number,
+ t: number
+): number {
+ return (1 + r / n) ** (t * n) * P;
}
-// let dp = 20;
-// for(let n = 0; n <= 8; n ++) {
-// x = FixedPointNumber.of(n, BigInt(dp));
-// r = x.sqrt();
-// console.log(`${n}, ${r};\t${Math.sqrt(n)};\t${BigNumber(n).dp(dp).sqrt()}`);
-// }
+// END-SNIPPET: FinancialMath_Functions