You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: text/0000-expand-math.md
+45Lines changed: 45 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -57,7 +57,52 @@ I foresee this as a primitive `Constant` with methods for each value (e.g., `Con
57
57
58
58
### `math/rational`
59
59
60
+
<<<<<<< HEAD
60
61
`math/rational` should decide backing precision on `create[A: Real]` and return precision on `apply[B: Number]` -- `let x = Rational.create[U64](where numerator = 2)` gives a type which is represented by embedded `U64`/`U64` and starts with a value of `2`/`1` which can then be returned via `x.apply[F32](): F32 => F32(2) / F32(1)`. `Rational` should be parameterized only on `Real` types and track sign via an embedded field.
62
+
=======
63
+
`math/rational` should decide backing precision on `create[A: UnsignedInteger]` and return precision on `apply[B: Number]` -- `let x = Rational.create[U64](where numerator=2)` gives a type which is represented by `U64(2)`/`U64(2)` which can then be returned as any valid `Number`. `Rational` should be parameterized only on `UnsignedInteger` types and track sign via an internal field.
64
+
65
+
```pony
66
+
// Parameterized on unsigned integers as negative status is tracked by field
67
+
class Rational[A: UnsignedInteger[A] val = USize]
68
+
var numerator: A
69
+
var denominator: A
70
+
var negative: Bool = false
71
+
72
+
// Allow for creating Rationals from signed or unsigned integer arguments
73
+
new create[B: Integer[B] val = ISize](n: B, d: B = 1)? =>
74
+
// Error if denominator is zero
75
+
if d == B.from[U8](0) then error end
76
+
77
+
// Produce unsigned equivalents of arguments
78
+
// NOTE: this produces an error of form
79
+
// Error:
80
+
// main.pony:XX:YY: type argument is outside its constraint
81
+
// This is because Integer is not a subtype of UnsignedInteger
82
+
let n': A = if n < B.from[U8](0) then A.from[B](-n) else A.from[B](n) end
83
+
let n': A = if n < B.from[U8](0) then A.from[B](-n) else A.from[B](n) end
84
+
let d': A = if d < B.from[U8](0) then A.from[B](-d) else A.from[B](d) end
85
+
86
+
// Find greatest common divisor and reduce fraction
87
+
let divisor: A = try GreatestCommonDivisor[A](n', d')? else A.from[U8](1) end
88
+
numerator = n' / divisor
89
+
denominator = d' / divisor
90
+
91
+
// Set negative field if numerator, but not denominator is negative
92
+
if (n < B.from[U8](0)) and (B.from[U8](0) < d) then
93
+
negative = true
94
+
end
95
+
96
+
fun string(): String =>
97
+
// Size of 10 here is a placeholder for determining the size needed
98
+
let output = recover String(10) end
99
+
if negative then output.append("-") end
100
+
output.append(numerator.string())
101
+
output.append(" / ")
102
+
output.append(denominator.string())
103
+
output
104
+
```
105
+
>>>>>>> Draft Rational implementation
61
106
62
107
Changing the underlying precision "in-place" is done via a `prec[C: Real]` method which creates a new instance with a different precision.
0 commit comments