2

iアルゴリズムで使用する必要があるだけです。そのようなタスクにはインポートclojure.mathはやり過ぎだと思います。

なんで?

複雑な結果は必要ありません。実際、虚部を持つ実部は必要ありません。私の実装では、一度に 1 つの値のみを使用し、乗算を除いて 2 つの値を結合することはありません。出力は への参照なしで終了しますi。虚数部は、計算で符号の変化を確認するためにのみ必要です。

簡単に言えば、次のように定義する方法があればいいのですがi

(def i (....) ) 

(* i i)等しい-1

4

3 に答える 3

3

(* i i)に評価したい場合は-1、マクロを準備する必要があります。

(ns user)
(defmacro *
  [& args]
  (let [i-count (count (filter #(= % 'i) args))
        error #(throw (Exception. "Illegal number of imaginary units."))
        i-factor (case (mod i-count 4)
                   0 1
                   2 -1
                   (error))]
    `(clojure.core/* ~@(conj (filter #(not= % 'i) args) i-factor))))

マクロは通常の乗算​​に展開され、実数の乗算を妨げません。

user=> (macroexpand '(* i i))
(clojure.core/* -1)
user=> (macroexpand '(* i i 5 i 6 i))
(clojure.core/* 1 5 6)
user=> (macroexpand '(* 1.3 3.7))
(clojure.core/* 1 1.3 3.7)
user=> (macroexpand '(* i (+ 2 3) i))
(clojure.core/* -1 (+ 2 3))

マクロは必要ですか?マクロiが存在しない場合(* i i) が評価されます。それらは定義されていないため、コンパイル時エラーが発生します。質問で示唆されているように、処理方法を知ってiいる値として定義できます。*それは可能ですが、実行時に評価されます。clojure.core/*マクロの明確な利点は、コンパイル中に評価され、上記の例に示すように通常の呼び出しに置き換えられることです。簡単に言えば速いです。

于 2012-11-27T11:13:15.920 に答える
1

すぐにハッキング*されたこのようなものはどうですか?

(defn hacked-* [& args]
  (let [[i-amount product] 
        ((juxt (comp count filter) 
               (comp #(apply * %) remove)) 
         #{:i} args)]
    (if (and (> i-amount 0) (even? i-amount)) 
      (- product)
      product)))


(hacked-* 1 2 3) => 6
(hacked-* 1 2 3 :i :i) => -6
(hacked-* 1 2 3 :i :i :i) => 6

複雑な式を評価するために、 * をハッキングされたバージョンに字句的に再バインドできます。

(let [* hacked-*]
 (* 1 :i 2 :i 3 :i (* :i :i))) => -6
于 2012-11-26T17:22:43.257 に答える
0

引数がすべて架空のものであると仮定する私のハックは次のとおりです。

(defn im* [& i] ((fn [q n] (([* str * str] q) ([1 'i -1 '-i] q) n)) (mod (count i) 4) (reduce * i)))

...最悪!しかし、たとえばNumbers.javaをハッキングして java.lang.Number の新しいサブタイプにディスパッチしない限り、あなたが求めていることは実際には不可能です。実際には、Java または Clojure の複素数ライブラリを使用する方が理にかなっています。

于 2012-11-27T01:23:15.877 に答える