লগ (বেস 2) ফাংশন লিখতে কোন উপায় আছে?
সি ভাষার 2 টি কার্যত বিল্ট রয়েছে - >>
1. log
যা বেস ই।
2. log10
বেস 10;
তবে এটি হিসাব করার জন্য আমার বেস 2 এর লগ ফাংশন প্রয়োজন।
লগ (বেস 2) ফাংশন লিখতে কোন উপায় আছে?
সি ভাষার 2 টি কার্যত বিল্ট রয়েছে - >>
1. log
যা বেস ই।
2. log10
বেস 10;
তবে এটি হিসাব করার জন্য আমার বেস 2 এর লগ ফাংশন প্রয়োজন।
উত্তর:
সাধারণ গণিত:
লগ 2 ( x ) = লগ y ( এক্স ) / লগ ওয় (2)
যেখানে y যে কোনও কিছু হতে পারে, যা স্ট্যান্ডার্ড লগ ফাংশনগুলির জন্য হয় 10 বা ই ।
সি 99 এর রয়েছে log2
(পাশাপাশি log2f
এবং log2l
ভাসমান এবং দীর্ঘ দ্বিগুণ)।
আপনি যদি একটি অবিচ্ছেদ্য ফলাফল খুঁজছেন, আপনি কেবলমাত্র মান সর্বাধিক বিট সেট নির্ধারণ করতে এবং তার অবস্থান ফিরে করতে পারেন।
Integer.highestOneBit(int)
পদ্ধতি থেকে নেওয়া ):i |= (i >> 1); i |= (i >> 2); i |= (i >> 4); i |= (i >> 8); i |= (i >> 16); return i - (i >>> 1);
while (i >>= 1) { ++l; }
i>>32
। তবে যেহেতু জাভাতে কেবল 32-বিট ইনট রয়েছে, এটি ঠিক আছে। সি / সি ++ এর জন্য এটি বিবেচনা করা দরকার।
যেমনটি http://en.wikedia.org/wiki/Logarithm এ বলেছে :
logb(x) = logk(x) / logk(b)
যা এর মানে হল যে:
log2(x) = log10(x) / log10(2)
log()
বাস্তবায়নের উত্সটি কখনই দেখে না এটি এটি করবে না। আমার খারাপ।
log10()
সি স্ট্যান্ডার্ডে কোনও ফাংশন সংজ্ঞায়িত করা হয়েছে, তাই সংকলক ফলাফলটি পূর্বাভাস সহ "বিশেষত" চিকিত্সা করতে মুক্ত, যা আমি বিশ্বাস করি @ জোহানেসের পরামর্শ?
log10(2)
একটি ধ্রুবক দ্বারা প্রতিস্থাপন করেছি।
আপনি যদি এটি দ্রুত তৈরি করতে চান তবে আপনি বিট টুইডলিং হ্যাকের মতো লুকিং টেবিল ব্যবহার করতে পারেন (কেবলমাত্র পূর্ণসংখ্যার লগ 2)।
uint32_t v; // find the log base 2 of 32-bit v
int r; // result goes here
static const int MultiplyDeBruijnBitPosition[32] =
{
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
};
v |= v >> 1; // first round down to one less than a power of 2
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
r = MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x07C4ACDDU) >> 27];
এ ছাড়া আপনার কম্পাইলারগুলির অন্তর্নির্মিত পদ্ধতিগুলি _BitScanReverse
যা দেখতে পারে সেদিকে নজর দেওয়া উচিত দ্রুততর হবে, কারণ এটি সম্পূর্ণরূপে হার্ডওয়্যার নির্ণিত হতে পারে।
সম্ভাব্য সদৃশটি একবার দেখে নিন কীভাবে সি ++ এ পূর্ণসংখ্যা লগ 2 () করবেন?
log2(x) = log10(x) / log10(2)
uint16_t log2(uint32_t n) {//but truncated
if (n==0) throw ...
uint16_t logValue = -1;
while (n) {//
logValue++;
n >>= 1;
}
return logValue;
}
মূলত টমলোগিকের মতোই ।
আপনাকে গণিত এইচ (সি) বা সিমাথ (সি ++) অন্তর্ভুক্ত করতে হবে অবশ্যই মনে রাখবেন যে আমাদের জানা গণিতগুলি আপনাকে অনুসরণ করতে হবে ... কেবল সংখ্যা> 0।
উদাহরণ:
#include <iostream>
#include <cmath>
using namespace std;
int main(){
cout<<log2(number);
}
আমার আরও স্পষ্টতা থাকা দরকার যে কেবলমাত্র উল্লেখযোগ্য বিটের অবস্থান এবং আমি যে মাইক্রোকন্ট্রোলারটি ব্যবহার করছিলাম তার কোনও গণিত গ্রন্থাগার ছিল না। আমি দেখতে পেয়েছি যে ইতিবাচক পূর্ণসংখ্যার মান আর্গুমেন্টের জন্য 2 ^ n মানের মধ্যে একটি লিনিয়ার সান্নিধ্য ব্যবহার করা ভালভাবে কাজ করে। কোডটি এখানে:
uint16_t approx_log_base_2_N_times_256(uint16_t n)
{
uint16_t msb_only = 0x8000;
uint16_t exp = 15;
if (n == 0)
return (-1);
while ((n & msb_only) == 0) {
msb_only >>= 1;
exp--;
}
return (((uint16_t)((((uint32_t) (n ^ msb_only)) << 8) / msb_only)) | (exp << 8));
}
আমার মূল প্রোগ্রামে, আমাকে পূর্ণসংখ্যার ফলাফল সহ এন * লগ 2 (এন) / 2 গণনা করতে হবে:
টেম্প = (((uint32_t) এন) * প্রায়_লগ_বেস_2_ এন_টাইমস_256) / 512;
এবং সমস্ত 16 বিট মান 2% এর বেশি দ্বারা বন্ধ ছিল না
উপরের সমস্ত উত্তর সঠিক। নীচের আমার এই উত্তর কারওর প্রয়োজন হলে সহায়ক হতে পারে। আমরা অনেকগুলি প্রশ্নে এই প্রয়োজনীয়তাটি দেখেছি যা আমরা সি ব্যবহার করে সমাধান করছি
log2 (x) = logy (x) / logy (2)
তবে, আপনি যদি সি ভাষা ব্যবহার করছেন এবং আপনি পূর্ণসংখ্যার ফলাফল চান, আপনি নিম্নলিখিত ব্যবহার করতে পারেন:
int result = (int)(floor(log(x) / log(2))) + 1;
আশাকরি এটা সাহায্য করবে.
উস্তামান সংগত যা করেছিলেন তার উন্নত সংস্করণ
static inline uint64_t
log2(uint64_t n)
{
uint64_t val;
for (val = 0; n > 1; val++, n >>= 1);
return val;
}