In the last bit in this REPL sequence, I want the negative and positive square root of 2 in a vector. So, I copy the ratio and paste it into a form.
$ clj
Clojure 1.9.0
user=> (require '[com.gfredericks.exact :as e])
nil
user=> (def TWO (e/native->integer 2))
#'user/TWO
user=> (defn square [x] (e/* x x))
#'user/square
user=> (defn avg [a b] (-> a (e/+ b) (e// TWO)))
#'user/avg
(defn newtonian-square-root
"Returns a ratio between (- (sqrt x) epsilon) and (+ (sqrt x) epsilon)"
[x epsilon]
(let [ee (square epsilon)]
(loop [guess (avg x e/ZERO)]
(if (-> guess square (e/- x) e/abs (e/< ee))
guess
(recur (-> x (e// guess) (avg guess)))))))
#'user/newtonian-square-root
(def epsilon
(e// (e/string->integer "1000000000000000000000000")))
#'user/epsilon
user=> (newtonian-square-root TWO epsilon)
1572584048032918633353217/1111984844349868137938112
user=> 1
1
user=> 2
2
user=> 3
3
user=> [(e/- 1572584048032918633353217/1111984844349868137938112) 1572584048032918633353217/1111984844349868137938112]
[-1572584048032918633353217/1111984844349868137938112 1572584048032918633353217/1111984844349868137938112]
ClojureScript without tagged literals for the ratios:
$ clj -m cljs.main -re node -r
ClojureScript 1.10.339
cljs.user=> (require '[com.gfredericks.exact :as e])
nil
cljs.user=> (def TWO (e/native->integer 2))
#'cljs.user/TWO
cljs.user=> (defn square [x] (e/* x x))
#'cljs.user/square
cljs.user=> (defn avg [a b] (-> a (e/+ b) (e// TWO)))
#'cljs.user/avg
(defn newtonian-square-root
"Returns a ratio between (- (sqrt x) epsilon) and (+ (sqrt x) epsilon)"
[x epsilon]
(let [ee (square epsilon)]
(loop [guess (avg x e/ZERO)]
(if (-> guess square (e/- x) e/abs (e/< ee))
guess
(recur (-> x (e// guess) (avg guess)))))))
#'cljs.user/newtonian-square-root
(def epsilon
(e// (e/string->integer "1000000000000000000000000")))
#'cljs.user/epsilon
cljs.user=> (newtonian-square-root TWO epsilon)
#object[com.gfredericks.exact.impl.Ratio]
cljs.user=> 1
1
cljs.user=> 2
2
cljs.user=> 3
3
cljs.user=>
^ Not sure what to do here.
Using tagged literals:
$ clj -i @precise/tagged_literals.cljc -m cljs.main -re node -r
ClojureScript 1.10.339
(require 'precise.tagged-literals
'[com.gfredericks.exact :as e])
nil
cljs.user=> (def TWO (e/native->integer 2))
#'cljs.user/TWO
cljs.user=> (defn square [x] (e/* x x))
#'cljs.user/square
cljs.user=> (defn avg [a b] (-> a (e/+ b) (e// TWO)))
#'cljs.user/avg
(defn newtonian-square-root
"Returns a ratio between (- (sqrt x) epsilon) and (+ (sqrt x) epsilon)"
[x epsilon]
(let [ee (square epsilon)]
(loop [guess (avg x e/ZERO)]
(if (-> guess square (e/- x) e/abs (e/< ee))
guess
(recur (-> x (e// guess) (avg guess)))))))
#'cljs.user/newtonian-square-root
(def epsilon
(e// (e/string->integer "1000000000000000000000000")))
#'cljs.user/epsilon
cljs.user=> (newtonian-square-root TWO epsilon)
#exact/ratio "1572584048032918633353217/1111984844349868137938112"
cljs.user=> 1
1
cljs.user=> 2
2
cljs.user=> 3
3
cljs.user=> [(e/- #exact/ratio "1572584048032918633353217/1111984844349868137938112") #exact/ratio "1572584048032918633353217/1111984844349868137938112"]
[#exact/ratio "-1572584048032918633353217/1111984844349868137938112" #exact/ratio "1572584048032918633353217/1111984844349868137938112"]