smalltalk: Number tower (Fraction, factorial, gcd:/lcm:, etc.) + 47 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
This commit is contained in:
@@ -369,6 +369,7 @@
|
||||
(st-class-define! "SmallInteger" "Integer" (list))
|
||||
(st-class-define! "LargePositiveInteger" "Integer" (list))
|
||||
(st-class-define! "Float" "Number" (list))
|
||||
(st-class-define! "Fraction" "Number" (list "numerator" "denominator"))
|
||||
(st-class-define! "Character" "Magnitude" (list "value"))
|
||||
;; Collections
|
||||
(st-class-define! "Collection" "Object" (list))
|
||||
@@ -679,6 +680,76 @@
|
||||
"peek
|
||||
self atEnd ifTrue: [^ nil].
|
||||
^ collection at: position + 1"))
|
||||
;; ── Fraction ──
|
||||
;; Rational numbers stored as numerator/denominator, normalized
|
||||
;; (sign on numerator, denominator > 0, reduced via gcd).
|
||||
(st-class-add-class-method! "Fraction" "numerator:denominator:"
|
||||
(st-parse-method
|
||||
"numerator: n denominator: d
|
||||
| f |
|
||||
f := super new.
|
||||
^ f setNumerator: n denominator: d"))
|
||||
(st-class-add-method! "Fraction" "setNumerator:denominator:"
|
||||
(st-parse-method
|
||||
"setNumerator: n denominator: d
|
||||
| g s nn dd |
|
||||
d = 0 ifTrue: [Error signal: 'Fraction denominator cannot be zero'].
|
||||
s := (d < 0) ifTrue: [-1] ifFalse: [1].
|
||||
nn := n * s. dd := d * s.
|
||||
g := nn abs gcd: dd.
|
||||
g = 0 ifTrue: [g := 1].
|
||||
numerator := nn / g.
|
||||
denominator := dd / g.
|
||||
^ self"))
|
||||
(st-class-add-method! "Fraction" "numerator"
|
||||
(st-parse-method "numerator ^ numerator"))
|
||||
(st-class-add-method! "Fraction" "denominator"
|
||||
(st-parse-method "denominator ^ denominator"))
|
||||
(st-class-add-method! "Fraction" "+"
|
||||
(st-parse-method
|
||||
"+ other
|
||||
^ Fraction
|
||||
numerator: numerator * other denominator + (other numerator * denominator)
|
||||
denominator: denominator * other denominator"))
|
||||
(st-class-add-method! "Fraction" "-"
|
||||
(st-parse-method
|
||||
"- other
|
||||
^ Fraction
|
||||
numerator: numerator * other denominator - (other numerator * denominator)
|
||||
denominator: denominator * other denominator"))
|
||||
(st-class-add-method! "Fraction" "*"
|
||||
(st-parse-method
|
||||
"* other
|
||||
^ Fraction
|
||||
numerator: numerator * other numerator
|
||||
denominator: denominator * other denominator"))
|
||||
(st-class-add-method! "Fraction" "/"
|
||||
(st-parse-method
|
||||
"/ other
|
||||
^ Fraction
|
||||
numerator: numerator * other denominator
|
||||
denominator: denominator * other numerator"))
|
||||
(st-class-add-method! "Fraction" "negated"
|
||||
(st-parse-method
|
||||
"negated ^ Fraction numerator: numerator negated denominator: denominator"))
|
||||
(st-class-add-method! "Fraction" "reciprocal"
|
||||
(st-parse-method
|
||||
"reciprocal ^ Fraction numerator: denominator denominator: numerator"))
|
||||
(st-class-add-method! "Fraction" "="
|
||||
(st-parse-method
|
||||
"= other
|
||||
^ numerator = other numerator and: [denominator = other denominator]"))
|
||||
(st-class-add-method! "Fraction" "<"
|
||||
(st-parse-method
|
||||
"< other
|
||||
^ numerator * other denominator < (other numerator * denominator)"))
|
||||
(st-class-add-method! "Fraction" "asFloat"
|
||||
(st-parse-method "asFloat ^ numerator / denominator"))
|
||||
(st-class-add-method! "Fraction" "printString"
|
||||
(st-parse-method
|
||||
"printString ^ numerator printString , '/' , denominator printString"))
|
||||
(st-class-add-method! "Fraction" "isFraction"
|
||||
(st-parse-method "isFraction ^ true"))
|
||||
"ok")))
|
||||
|
||||
;; Initialise on load. Tests can re-bootstrap to reset state.
|
||||
|
||||
Reference in New Issue
Block a user