fixes on Decimals and bound kotlin classes
This commit is contained in:
1 parent
c7c333b71a
commit
05d7432b37
14 files changed
+114
-667
No files matched your search
+36
-16
@@ -8,9 +8,9 @@ Import it when you need decimal arithmetic that should not inherit `Real`'s bina
|
||||
import lyng.decimal
|
||||
```
|
||||
|
||||
## What `BigDecimal` Is For
|
||||
## What `Decimal` Is For
|
||||
|
||||
Use `BigDecimal` when values are fundamentally decimal:
|
||||
Use `Decimal` when values are fundamentally decimal:
|
||||
|
||||
- money
|
||||
- human-entered quantities
|
||||
@@ -38,8 +38,8 @@ assertEquals("2.2", c.toStringExpanded())
|
||||
|
||||
The three forms mean different things:
|
||||
|
||||
- `1.d`: convert `Int -> BigDecimal`
|
||||
- `2.2.d`: convert `Real -> BigDecimal`
|
||||
- `1.d`: convert `Int -> Decimal`
|
||||
- `2.2.d`: convert `Real -> Decimal`
|
||||
- `"2.2".d`: parse exact decimal text
|
||||
|
||||
That distinction is intentional.
|
||||
@@ -67,16 +67,36 @@ The explicit factory methods are:
|
||||
```lyng
|
||||
import lyng.decimal
|
||||
|
||||
BigDecimal.fromInt(10)
|
||||
BigDecimal.fromReal(2.5)
|
||||
BigDecimal.fromString("12.34")
|
||||
Decimal.fromInt(10)
|
||||
Decimal.fromReal(2.5)
|
||||
Decimal.fromString("12.34")
|
||||
```
|
||||
|
||||
These are equivalent to the conversion-property forms, but sometimes clearer in APIs or generated code.
|
||||
|
||||
## From Kotlin
|
||||
|
||||
If you already have an ionspin `BigDecimal` on the host side, the simplest supported way to create a Lyng `Decimal` is:
|
||||
|
||||
```kotlin
|
||||
import com.ionspin.kotlin.bignum.decimal.BigDecimal
|
||||
import net.sergeych.lyng.Script
|
||||
import net.sergeych.lyng.asFacade
|
||||
import net.sergeych.lyng.newDecimal
|
||||
|
||||
val scope = Script.newScope()
|
||||
val decimal = scope.asFacade().newDecimal(BigDecimal.parseStringWithMode("12.34"))
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- `newDecimal(...)` loads `lyng.decimal` if needed
|
||||
- it returns a real Lyng `Decimal` object instance
|
||||
- this is the preferred Kotlin-side construction path when you already hold a host `BigDecimal`
|
||||
|
||||
## Core Operations
|
||||
|
||||
`BigDecimal` supports:
|
||||
`Decimal` supports:
|
||||
|
||||
- `+`
|
||||
- `-`
|
||||
@@ -115,7 +135,7 @@ assert(2 == 2.d)
|
||||
assert(3 > 2.d)
|
||||
```
|
||||
|
||||
Without this registration mechanism, only the cases directly implemented on the left-hand class would work. The bridge fills the gap for expressions such as `Int + BigDecimal` and `Real + BigDecimal`.
|
||||
Without this registration mechanism, only the cases directly implemented on the left-hand class would work. The bridge fills the gap for expressions such as `Int + Decimal` and `Real + Decimal`.
|
||||
|
||||
See [OperatorInterop.md](OperatorInterop.md) for the generic mechanism behind that.
|
||||
|
||||
@@ -226,7 +246,7 @@ assertEquals("-0.12", withDecimalContext(2, DecimalRounding.HalfTowardsZero) { (
|
||||
## Decimal With Stdlib Math Functions
|
||||
|
||||
Core math helpers such as `abs`, `floor`, `ceil`, `round`, `sin`, `exp`, `ln`, `sqrt`, `log10`, `log2`, and `pow`
|
||||
now also accept `BigDecimal`.
|
||||
now also accept `Decimal`.
|
||||
|
||||
Current behavior is intentionally split:
|
||||
|
||||
@@ -235,7 +255,7 @@ Current behavior is intentionally split:
|
||||
- `floor(x)`
|
||||
- `ceil(x)`
|
||||
- `round(x)`
|
||||
- `pow(x, y)` when `x` is `BigDecimal` and `y` is an integral exponent
|
||||
- `pow(x, y)` when `x` is `Decimal` and `y` is an integral exponent
|
||||
- temporary bridge through `Real`:
|
||||
- `sin`, `cos`, `tan`
|
||||
- `asin`, `acos`, `atan`
|
||||
@@ -248,7 +268,7 @@ Current behavior is intentionally split:
|
||||
The temporary bridge is:
|
||||
|
||||
```lyng
|
||||
BigDecimal -> Real -> host math -> BigDecimal
|
||||
Decimal -> Real -> host math -> Decimal
|
||||
```
|
||||
|
||||
This is a compatibility step, not the long-term design. Native decimal implementations will replace these bridge-based
|
||||
@@ -259,12 +279,12 @@ Examples:
|
||||
```lyng
|
||||
import lyng.decimal
|
||||
|
||||
assertEquals("2.5", (abs("-2.5".d) as BigDecimal).toStringExpanded())
|
||||
assertEquals("2", (floor("2.9".d) as BigDecimal).toStringExpanded())
|
||||
assertEquals("2.5", (abs("-2.5".d) as Decimal).toStringExpanded())
|
||||
assertEquals("2", (floor("2.9".d) as Decimal).toStringExpanded())
|
||||
|
||||
// Temporary Real bridge:
|
||||
assertEquals((exp(1.25) as Real).d.toStringExpanded(), (exp("1.25".d) as BigDecimal).toStringExpanded())
|
||||
assertEquals((sqrt(2.0) as Real).d.toStringExpanded(), (sqrt("2".d) as BigDecimal).toStringExpanded())
|
||||
assertEquals((exp(1.25) as Real).d.toStringExpanded(), (exp("1.25".d) as Decimal).toStringExpanded())
|
||||
assertEquals((sqrt(2.0) as Real).d.toStringExpanded(), (sqrt("2".d) as Decimal).toStringExpanded())
|
||||
```
|
||||
|
||||
If you care about exact decimal source text:
|
||||
|
||||
@@ -160,15 +160,15 @@ import lyng.decimal
|
||||
3 > 2.d
|
||||
```
|
||||
|
||||
work naturally even though `Int` and `Real` themselves were not edited to know `BigDecimal`.
|
||||
work naturally even though `Int` and `Real` themselves were not edited to know `Decimal`.
|
||||
|
||||
The shape is:
|
||||
|
||||
- `leftClass = Int` or `Real`
|
||||
- `rightClass = BigDecimal`
|
||||
- `commonClass = BigDecimal`
|
||||
- convert built-ins into `BigDecimal`
|
||||
- leave `BigDecimal` values unchanged
|
||||
- `rightClass = Decimal`
|
||||
- `commonClass = Decimal`
|
||||
- convert built-ins into `Decimal`
|
||||
- leave `Decimal` values unchanged
|
||||
|
||||
## Step-By-Step Pattern For Your Own Type
|
||||
|
||||
|
||||
@@ -15,9 +15,9 @@ Sources: `lynglib/src/commonMain/kotlin/net/sergeych/lyng/Script.kt`, `lynglib/s
|
||||
- Preconditions: `require`, `check`.
|
||||
- Async/concurrency: `launch`, `yield`, `flow`, `delay`.
|
||||
- Math: `floor`, `ceil`, `round`, `sin`, `cos`, `tan`, `asin`, `acos`, `atan`, `sinh`, `cosh`, `tanh`, `asinh`, `acosh`, `atanh`, `exp`, `ln`, `log10`, `log2`, `pow`, `sqrt`, `abs`, `clamp`.
|
||||
- These helpers also accept `lyng.decimal.BigDecimal`.
|
||||
- These helpers also accept `lyng.decimal.Decimal`.
|
||||
- Exact Decimal path today: `abs`, `floor`, `ceil`, `round`, and `pow` with integral exponent.
|
||||
- Temporary Decimal path for the rest: convert `BigDecimal -> Real`, compute, then convert back to `BigDecimal`.
|
||||
- Temporary Decimal path for the rest: convert `Decimal -> Real`, compute, then convert back to `Decimal`.
|
||||
- Treat that bridge as temporary; prefer native Decimal implementations when they become available.
|
||||
|
||||
## 3. Core Global Constants/Types
|
||||
@@ -60,6 +60,9 @@ Sources: `lynglib/src/commonMain/kotlin/net/sergeych/lyng/Script.kt`, `lynglib/s
|
||||
## 5. Additional Built-in Modules (import explicitly)
|
||||
- `import lyng.observable`
|
||||
- `Observable`, `Subscription`, `ObservableList`, `ListChange` and change subtypes, `ChangeRejectionException`.
|
||||
- `import lyng.decimal`
|
||||
- `Decimal`, `DecimalContext`, `DecimalRounding`, `withDecimalContext(...)`.
|
||||
- Kotlin host helper: `ScopeFacade.newDecimal(BigDecimal)` wraps an ionspin host decimal as a Lyng `Decimal`.
|
||||
- `import lyng.complex`
|
||||
- `Complex`, `complex(re, im)`, `cis(angle)`, and numeric embedding extensions such as `2.i` / `3.re`.
|
||||
- `import lyng.matrix`
|
||||
|
||||
+11
-11
@@ -62,9 +62,9 @@ but:
|
||||
|
||||
The following functions return the argument unchanged if it is `Int`.
|
||||
|
||||
For `BigDecimal`:
|
||||
For `Decimal`:
|
||||
- `floor(x)`, `ceil(x)`, and `round(x)` currently use exact decimal operations
|
||||
- the result stays `BigDecimal`
|
||||
- the result stays `Decimal`
|
||||
|
||||
For `Real`, the result is a transformed `Real`.
|
||||
|
||||
@@ -78,11 +78,11 @@ For `Real`, the result is a transformed `Real`.
|
||||
## Lyng math functions
|
||||
|
||||
Decimal note:
|
||||
- all scalar math helpers accept `BigDecimal`
|
||||
- `abs(x)` stays exact for `BigDecimal`
|
||||
- `pow(x, y)` is exact for `BigDecimal` when `y` is an integral exponent
|
||||
- the remaining `BigDecimal` cases currently use a temporary bridge:
|
||||
`BigDecimal -> Real -> host math -> BigDecimal`
|
||||
- all scalar math helpers accept `Decimal`
|
||||
- `abs(x)` stays exact for `Decimal`
|
||||
- `pow(x, y)` is exact for `Decimal` when `y` is an integral exponent
|
||||
- the remaining `Decimal` cases currently use a temporary bridge:
|
||||
`Decimal -> Real -> host math -> Decimal`
|
||||
- this is temporary; native decimal implementations are planned
|
||||
|
||||
| name | meaning |
|
||||
@@ -104,7 +104,7 @@ Decimal note:
|
||||
| log10(x) | $log_{10}(x)$ |
|
||||
| pow(x, y) | ${x^y}$ |
|
||||
| sqrt(x) | $ \sqrt {x}$ |
|
||||
| abs(x) | absolute value of x. Int if x is Int, BigDecimal if x is BigDecimal, Real otherwise |
|
||||
| abs(x) | absolute value of x. Int if x is Int, Decimal if x is Decimal, Real otherwise |
|
||||
| clamp(x, range) | limit x to be inside range boundaries |
|
||||
|
||||
For example:
|
||||
@@ -120,9 +120,9 @@ For example:
|
||||
import lyng.decimal
|
||||
|
||||
// Decimal-aware math works too. Some functions are exact, some still bridge through Real temporarily:
|
||||
assert( (abs("-2.5".d) as BigDecimal).toStringExpanded() == "2.5" )
|
||||
assert( (floor("2.9".d) as BigDecimal).toStringExpanded() == "2" )
|
||||
assert( sin("0.5".d) is BigDecimal )
|
||||
assert( (abs("-2.5".d) as Decimal).toStringExpanded() == "2.5" )
|
||||
assert( (floor("2.9".d) as Decimal).toStringExpanded() == "2" )
|
||||
assert( sin("0.5".d) is Decimal )
|
||||
|
||||
// clamp() limits value to the range:
|
||||
assert( clamp(15, 0..10) == 10 )
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ Lyng now ships a first-class decimal module built as a regular extension library
|
||||
|
||||
It provides:
|
||||
|
||||
- `BigDecimal`
|
||||
- `Decimal`
|
||||
- convenient `.d` conversions from `Int`, `Real`, and `String`
|
||||
- mixed arithmetic with `Int` and `Real`
|
||||
- local division precision and rounding control via `withDecimalContext(...)`
|
||||
|
||||
Reference in new issue
Block a user