fixed some issues with Decimals
This commit is contained in:
1 parent
e55d9c835a
commit
c7c333b71a
11 files changed
+385
-73
No files matched your search
@@ -223,6 +223,50 @@ assertEquals("-0.12", withDecimalContext(2, DecimalRounding.HalfTowardsZero) { (
|
||||
|
||||
## Recommended Usage Rules
|
||||
|
||||
## 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`.
|
||||
|
||||
Current behavior is intentionally split:
|
||||
|
||||
- exact decimal implementation:
|
||||
- `abs(x)`
|
||||
- `floor(x)`
|
||||
- `ceil(x)`
|
||||
- `round(x)`
|
||||
- `pow(x, y)` when `x` is `BigDecimal` and `y` is an integral exponent
|
||||
- temporary bridge through `Real`:
|
||||
- `sin`, `cos`, `tan`
|
||||
- `asin`, `acos`, `atan`
|
||||
- `sinh`, `cosh`, `tanh`
|
||||
- `asinh`, `acosh`, `atanh`
|
||||
- `exp`, `ln`, `log10`, `log2`
|
||||
- `sqrt`
|
||||
- `pow` for the remaining non-integral decimal exponent cases
|
||||
|
||||
The temporary bridge is:
|
||||
|
||||
```lyng
|
||||
BigDecimal -> Real -> host math -> BigDecimal
|
||||
```
|
||||
|
||||
This is a compatibility step, not the long-term design. Native decimal implementations will replace these bridge-based
|
||||
paths over time.
|
||||
|
||||
Examples:
|
||||
|
||||
```lyng
|
||||
import lyng.decimal
|
||||
|
||||
assertEquals("2.5", (abs("-2.5".d) as BigDecimal).toStringExpanded())
|
||||
assertEquals("2", (floor("2.9".d) as BigDecimal).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())
|
||||
```
|
||||
|
||||
If you care about exact decimal source text:
|
||||
|
||||
```lyng
|
||||
|
||||
@@ -15,6 +15,10 @@ 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`.
|
||||
- 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`.
|
||||
- Treat that bridge as temporary; prefer native Decimal implementations when they become available.
|
||||
|
||||
## 3. Core Global Constants/Types
|
||||
- Values: `Unset`, `π`.
|
||||
|
||||
+23
-3
@@ -60,8 +60,13 @@ but:
|
||||
|
||||
## Round and range
|
||||
|
||||
The following functions return its argument if it is `Int`,
|
||||
or transformed `Real` otherwise.
|
||||
The following functions return the argument unchanged if it is `Int`.
|
||||
|
||||
For `BigDecimal`:
|
||||
- `floor(x)`, `ceil(x)`, and `round(x)` currently use exact decimal operations
|
||||
- the result stays `BigDecimal`
|
||||
|
||||
For `Real`, the result is a transformed `Real`.
|
||||
|
||||
| name | description |
|
||||
|----------------|--------------------------------------------------------|
|
||||
@@ -72,6 +77,14 @@ or transformed `Real` otherwise.
|
||||
|
||||
## 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`
|
||||
- this is temporary; native decimal implementations are planned
|
||||
|
||||
| name | meaning |
|
||||
|-----------|------------------------------------------------------|
|
||||
| sin(x) | sine |
|
||||
@@ -91,7 +104,7 @@ or transformed `Real` otherwise.
|
||||
| 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, Real otherwise |
|
||||
| abs(x) | absolute value of x. Int if x is Int, BigDecimal if x is BigDecimal, Real otherwise |
|
||||
| clamp(x, range) | limit x to be inside range boundaries |
|
||||
|
||||
For example:
|
||||
@@ -104,6 +117,13 @@ For example:
|
||||
assert( abs(-1) is Int)
|
||||
assert( abs(-2.21) == 2.21 )
|
||||
|
||||
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 )
|
||||
|
||||
// clamp() limits value to the range:
|
||||
assert( clamp(15, 0..10) == 10 )
|
||||
assert( clamp(-5, 0..10) == 0 )
|
||||
|
||||
Reference in new issue
Block a user