ক্লোজারে এক্সপেনশনেশন কীভাবে করবেন?


106

আমি কীভাবে ক্লোজারে এক্সপেনশনেশন করতে পারি? আপাতত আমার কেবল পূর্ণসংখ্যার ক্ষয়ক্ষতি প্রয়োজন, তবে প্রশ্নটি ভগ্নাংশের ক্ষেত্রেও যায়।


18
যে কেউ ক্লোজার জানে না, তবে এটি পছন্দ করতে পারে (লিসপ, ফাংশনাল প্রোগ্রামিং এবং প্রচুর উপায়ে গ্রন্থাগার রয়েছে তার অনুরাগী) হিসাবে, আমি হতাশ হয়েছি যে এই সাধারণ প্রশ্নের অনেক উত্তর রয়েছে - বা এটি মোটেই জিজ্ঞাসা করতে হয়েছিল। আমি ভেবেছিলাম যে ক্ষতচিহ্নকরণ বিশেষভাবে কিছু না করে প্রদত্ত মৌলিক ফাংশনগুলির মধ্যে একটি হবে। যদিও আমি এটি জিজ্ঞাসা করা হয়েছিল খুশি।
মঙ্গল

1
হ্যাঁ সম্ভবত এটির কিছু সংস্করণ মূল হওয়া উচিত ... তবে আমি মনে করি যে অনেক উত্তর এখনও একটি ভাল চিহ্ন। "বাস্তবায়নের একাধিক পাথ" মনে হচ্ছে কারণ এগুলি প্রচুর পরিমাণে সরবরাহ করা হয়নি - ব্যবহারকারীর দক্ষতার জন্য তারা যে ক্রিয়াকলাপটি ব্যবহার করছে তার বিশদটি জানতে হবে। উদাহরণস্বরূপ (নির্বাচিত উত্তরে যেমন উল্লেখ করা হয়েছে) কিছু উপায় সম্ভাব্যভাবে স্ট্যাকটি ফুটিয়ে তুলতে পারে, অন্যরা এটির সম্ভাবনা কম করে। সম্ভবত কিছু অলস, কিছু উত্সাহী ... ক্লোজুরে কিছু বিবরণ দেওয়া উচিত যা সমস্ত বিবরণ, যে কারণে আমি মনে করি যে সবচেয়ে অ-তুচ্ছ
লিওব

3
আমি মনে করি যে কেবলমাত্র কোনও এক্সপ ফাংশন নেই তার কারণ হ'ল ক্লোজুরের সংখ্যাযুক্ত টাওয়ারটি দক্ষতার কারণে খারাপভাবে ভেঙে গেছে। সুতরাং ক্ষুদ্রাকর্ষণ দ্বারা আপনি বোঝাতে পারেন এমন বিভিন্ন ধরণের বিভিন্ন জিনিস রয়েছে। (মেয়াদোত্তীর্ণ 2 (Exp 2 200)) কী হওয়া উচিত? একটি ত্রুটি বা একটি বিশাল পূর্ণসংখ্যা যা গণনা করতে একটি বয়স নেয়? আপনি যদি কেবল স্বাভাবিক ভাসমান পয়েন্ট এক্সপ চান, তবে জাভাটি অন্তর্নির্মিত। আপনি যদি এমন কোনও ভাষা চান যেখানে সংখ্যাগুলি বাস্তবের মতো কাজ করার জন্য সর্বোত্তম চেষ্টা করে এবং ব্যয় স্থগিত করে, ক্লোজারের পরিবর্তে স্কিমটি ব্যবহার করুন।
জন লরেন্স Aspden

উত্তর:


141

ক্লাসিক পুনরাবৃত্তি (এটি দেখুন, এটি স্ট্যাকটি উড়িয়ে দেয়)

(defn exp [x n]
     (if (zero? n) 1
         (* x (exp x (dec n)))))

লেজ পুনরাবৃত্তি

(defn exp [x n]
  (loop [acc 1 n n]
    (if (zero? n) acc
        (recur (* x acc) (dec n)))))

ক্রিয়ামূলক

(defn exp [x n]
  (reduce * (repeat n x)))

লুক্কায়িত (এছাড়াও স্ট্যাক ঘা, কিন্তু এত সহজে না)

(defn exp-s [x n]
  (let [square (fn[x] (* x x))]
    (cond (zero? n) 1
          (even? n) (square (exp-s x (/ n 2)))
          :else (* x (exp-s x (dec n))))))

গ্রন্থাগার

(require 'clojure.contrib.math)

11
বিনোদনমূলক উত্তর!
ম্যাট ফেনউইক

নিচে গোপন সমাধান সম্পূর্ণরূপে পুনরাবৃত্ত সংস্করণ দেখতে stackoverflow.com/a/22977674/231589
কার্ল Rosaen

5
Clojure.contrib.math এখন অবহিত করা হয়েছে, দেখুন ম্যাথ.সংখ্যক-টাওয়ার
alvaro g

দ্বিতীয় পরামর্শ (লেজ পুনরাবৃত্ত) এর এন <0 এর জন্য পূর্ণসংখ্যার ওভারফ্লো হয়েছে
পয়েন্টো সেনশি

1
চমত্কার উত্তর। এখানে একটি ম্যাক্রো সঙ্গে এটা দিয়ে কি করতে হয় তা দেখুন: (defmacro মেপুঃ [XN] `(* ~ @ (নিন এন (পুনরাবৃত্তি এক্স))))
ড্যানিয়েল Szmulewicz

78

ক্লোজারের একটি পাওয়ার ফাংশন রয়েছে যা ভালভাবে কাজ করে: আমি জাভা ইন্টারপ হয়ে যাওয়ার পরিবর্তে এটি ব্যবহার করার পরামর্শ দিচ্ছি কারণ এটি ক্লোজারের স্বেচ্ছাসেবী-নির্ভুলতার সংখ্যার সঠিকভাবে পরিচালনা করে। এটি নেমস্পেসে Clojure.math.numeric - টাওয়ার

এটা তোলে বলা হচ্ছে exptজন্য exponentiation বদলে powerবা powযা হয়তো ব্যাখ্যা দিয়েছে কেন একটু কঠিন এটি আছে ... যাহাই হউক না কেন এখানে একটি ছোট উদাহরণ (নোট যে useকাজ কিন্তু ভালো ব্যবহার require):

(require '[clojure.math.numeric-tower :as math :refer [expt]])  ; as of Clojure 1.3
;; (use 'clojure.contrib.math)     ; before Clojure 1.3
(expt 2 200)
=> 1606938044258990275541962092341162602522202993782792835301376

প্যাকেজ ইনস্টলেশন সম্পর্কে অনুস্মারক

org.clojure.math.numeric-towerক্লোজুর নেমস্পেসটি clojure.math.numeric-towerঅ্যাক্সেসযোগ্য করার জন্য আপনাকে প্রথমে জাভা প্যাকেজটি ইনস্টল করতে হবে !

কমান্ড লাইনে:

$ lein new my-example-project
$ cd lein new my-example-project

তারপরে সম্পাদনা করুন project.cljএবং [org.clojure/math.numeric-tower "0.0.4"]নির্ভরতা ভেক্টরে যুক্ত করুন।

একটি লাইন আরপিএল শুরু করুন (ক্লোজার রিপ্লে নয়)

$ lein repl

এখন:

(require '[clojure.math.numeric-tower :as math])
(math/expt 4 2)
;=> 16

অথবা

(require '[clojure.math.numeric-tower :as math :refer [expt]])
(expt 4 2)
;=> 16

1
সম্ভবত অজানা কারণ এটি স্ট্যান্ডার্ড ক্লোজারের অংশ বলে মনে হচ্ছে না। 1.3.0 যখন আমি এইভাবে এটি করার চেষ্টা করি তখন math.clj সনাক্ত করতে সক্ষম না হওয়া সম্পর্কে ত্রুটি টস করে।
ব্রায়ান নোব্লাচ

9
আমি মনে করি এটি এখন "Clojure.math.numeric - টাওয়ার" এ ১.৩ অনুসারে (যেহেতু Clojure.contrib পৃথক গ্রন্থাগারে বিভক্ত হয়ে গেছে)
মাইক্রা

ব্যবহারকারীর হতাশা প্রশমিত করতে "প্যাকেজ ইনস্টলেশন সম্পর্কে অনুস্মারক" যুক্ত করা হয়েছে।
ডেভিড টোনহোফার

60

আপনি জাভা Math.powবা BigInteger.powপদ্ধতি ব্যবহার করতে পারেন :

(Math/pow base exponent)

(.pow (bigint base) exponent)

+1, যদিও আমি জানি আপনি জাভা লিবসের সাথে ইন্টারপপ করতে পারেন; যাইহোক, 1) ম্যাথ.পাউ ডাবলসের সাথে কাজ করে, আমার পূর্ণসংখ্যার দরকার, আপনি একটি উদাহরণ দিতে পারেন? 2) আপনার কি সত্যিই স্টেথের জন্য ইন্টারপ ব্যবহার করতে হবে? ক্ষমতা হিসাবে সহজ?
পিটার

জাভা লাইব্রেরিগুলির চারপাশে ক্লোজার তৈরি করা হয়েছে, এটি যা ভাঙা হয়নি তা ঠিক করার চেষ্টা করে না এবং ম্যাথ / পাও ঠিক কাজ করে। আপনার দ্বিগুণ বা পূর্ণসংখ্যার যত্ন নেওয়া কেন দরকার? আপনি এই ব্যবহার করতে পারে richhickey.github.com/clojure-contrib/...
DaVinci

1
@ পিটার: ১) যদি আপনার শক্তি এত বড় না হয় যে সেগুলি ডাবলস দ্বারা আর সঠিকভাবে উপস্থাপন করা যায় না, কেবল ফলাফলটি ইন্টাস্ট করার ক্ষেত্রে আসলেই কোনও সমস্যা নেই। 2) ক্লোজারের সমতুল্য হলে লেখার Math/powচেয়ে math-powনামটি যা কিছু জটিল বা কী জটিল তা আমি দেখতে পাই না । যদি ইতিমধ্যে যদি একটি সাধারণ জাভা পদ্ধতি থাকে যা আপনি যা করেন তা করেন তবে ক্লোজারে কার্যকারিতাটি পুনরায় তৈরি করার কোনও কারণ নেই। জাভা ইন্টারপ সহজাত ক্ষতিকারক নয়।
sepp2k

3
@ দা ভিঞ্চি: অদ্ভুত মন্তব্য, এটি নিজস্ব নিজস্ব একটি ভাষা এবং জাভাতে রয়েছে এমন অনেকগুলি কার্যকারিতা রয়েছে (স্ট্রিংরেভারের মতো)
পিটার

4
আমি যদি মনে করি আপনি সঠিক বিগিনটেজার শক্তি চান তবে আপনি ক্লোজারের ক্লোজার কন্ট্রিবি.ম্যাথ / এক্সপেটটি আরও ভাল ব্যবহার করছেন I সম্ভবত হুডের নীচে একই কাজ করে তবে জাভা ইন্টারপ হয়ে যাওয়ার চেয়ে খুব সুন্দর .....
মাইক্রা

13

এই প্রশ্নটি যখন প্রাথমিকভাবে জিজ্ঞাসা করা হয়েছিল, Clojure.contrib.math / expt এটি করার জন্য অফিসিয়াল গ্রন্থাগারের কাজ ছিল। সেই থেকে এটি Clojure.math.numericmeric টাওয়ারে চলে গেছে


+1 এই উত্তরের জন্য যেহেতু এটি ক্লোজার সঠিকভাবে (যেমন বিগডিসিমাল / বিগইন্টিজার) পাটিগণিত সঠিকভাবে পরিচালনা করে।
মাইক্রা


8
user=> (.pow (BigInteger. "2") 10)
1024
user=> (.pow (BigInteger. "2") 100)
1267650600228229401496703205376

6
এছাড়াও আপনি এর জন্য আক্ষরিক স্বরলিপিটি ব্যবহার করতে পারেন:(.pow 2M 100)
গোলমাল

1
তাদের ধরণগুলি আলাদা। ব্যবহারকারী => (টাইপ 2 এম) জাভা.ম্যাথ.বিগডিসিমাল ব্যবহারকারী => (টাইপ (বিগইন্টিজার। "2")) জাভা.ম্যাথ.বিগইনটেইজার
কিম তাইজিউন

ইমো সেরা সমাধান, শোয়ার, বিদ্যমান লাইব্রেরি ব্যবহার করে এবং বিগিন্ট পরিচালনা করা সহ। +1
ড্যানিয়েল গ্রাসস্কেক

আমার (Math/pow Math/E x)জন্য কৌতুক করে তোলে ( Math/Eআপনার পছন্দের বেসটি প্রতিস্থাপন )।
জাজ

6

আপনার যদি সত্যিই কোনও ক্রিয়াকলাপের প্রয়োজন হয় এবং কোনও পদ্ধতি না হয় তবে আপনি কেবল এটি মুছতে পারেন:

 (defn pow [b e] (Math/pow b e))

এবং এই ফাংশনে আপনি এটিতে intবা অনুরূপ কাস্ট করতে পারেন । ফাংশনগুলি প্রায়শই বেশি কার্যকর যে পদ্ধতিগুলি কারণ আপনি এগুলিকে অন্য ফাংশনের পরামিতি হিসাবে পাস করতে পারেন - এই ক্ষেত্রে mapআমার মনে আসে।

আপনার যদি সত্যিই জাভা ইন্টারপ এড়ানো প্রয়োজন, আপনি নিজের পাওয়ার ফাংশনটি লিখতে পারেন। উদাহরণস্বরূপ, এটি একটি সাধারণ ফাংশন:

 (defn pow [n p] (let [result (apply * (take (abs p) (cycle [n])))]
   (if (neg? p) (/ 1 result) result)))

এটি পূর্ণসংখ্যার বেদী (যেমন কোনও শিকড় নয়) এর জন্য পাওয়ার গণনা করে।

এছাড়াও, যদি আপনি বড় সংখ্যক নিয়ে কাজ করে থাকেন তবে আপনি এর BigIntegerপরিবর্তে ব্যবহার করতে পারেন int

এবং যদি আপনি খুব সংখ্যক সংখ্যার সাথে ডিল করছেন , আপনি তাদের অঙ্কের তালিকা হিসাবে প্রকাশ করতে চাইতে পারেন এবং ফলাফলটি গণনা করার সাথে সাথে ফলাফলগুলিকে অন্য কোনও স্ট্রিমে আউটপুট দেওয়ার কারণে আপনার নিজের গাণিতিক ক্রিয়াগুলি তাদের উপরে প্রবাহিত করতে লিখতে পারেন।





2

লেজ পুনরাবৃত্তি এবং নেতিবাচক ঘনিষ্ঠ সমর্থনকারী "স্নিগ্ধ" পদ্ধতির বাস্তবায়ন:

(defn exp
  "exponent of x^n (int n only), with tail recursion and O(logn)"
   [x n]
   (if (< n 0)
     (/ 1 (exp x (- n)))
     (loop [acc 1
            base x
            pow n]
       (if (= pow 0)
         acc                           
         (if (even? pow)
           (recur acc (* base base) (/ pow 2))
           (recur  (* acc base) base (dec pow)))))))


1

চেষ্টা

(defn pow [x n]
  (loop [x x n n r 1]
    (cond
      (= n 0) r
      (even? n) (recur (* x x) (/ n 2) r)
      :else (recur x (dec n) (* r x)))))

একটি লেজ পুনরুক্তিযোগ্য ও (লগ এন) সমাধানের জন্য, আপনি যদি এটি নিজে প্রয়োগ করতে চান (কেবলমাত্র ইতিবাচক পূর্ণসংখ্যার সমর্থন করে)। স্পষ্টতই, আরও ভাল সমাধান হ'ল লাইব্রেরির ফাংশনগুলি ব্যবহার করা যা অন্যরা উল্লেখ করেছে।


0

কিভাবে সম্পর্কে Clojure.contrib.genric.math- ফাংশন

Clojure.contrib.generic.math- ফাংশন লাইব্রেরিতে একটি পাওয়ার ফাংশন রয়েছে। এটি ম্যাথ.প্যাওয়ের কাছে কেবলমাত্র একটি ম্যাক্রো এবং জাভা গণিত ফাংশনটি কল করার আরও "ক্লোজারিশ" উপায়।

http://clojure.github.com/clojure-contrib/generic.math-functions-api.html#clojure.contrib.generic.math-functions/pow


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.