বাইট থেকে একটি নির্দিষ্ট বিট পান


98

আমার একটি বাইট আছে, বিশেষত বাইট অ্যারে থেকে একটি বাইট যা অন্য ডিভাইস থেকে প্রেরিত ইউডিপির মাধ্যমে এসেছিল। এই বাইটটি ডিভাইসে 8 রিলে অন / অফ স্টেট সংরক্ষণ করে।

আমি কীভাবে একটি নির্দিষ্ট বিটের মান পেতে পারি? আদর্শভাবে একটি এক্সটেনশন পদ্ধতিটি সবচেয়ে মার্জিত দেখায় এবং একটি বিল ফিরিয়ে দেওয়া আমার কাছে সবচেয়ে বেশি অর্থবোধ করে।

public static bool GetBit(this byte b, int bitNumber)
{
    //black magic goes here
}

উত্তর:


182

সহজ। আপনার সংখ্যাটি 2 ^ বিট নাম্বারের সাথে তুলনা করতে কিছুটা বিছিন্নভাবে এবং ব্যবহার করুন যা বিট-শিফটিংয়ের মাধ্যমে সস্তাভাবে গণনা করা যেতে পারে।

//your black magic
var bit = (b & (1 << bitNumber-1)) != 0;

সম্পাদনা: আরও কিছু বিশদ যুক্ত করতে কারণ অনেকগুলি অনুরূপ উত্তর রয়েছে যার ব্যাখ্যা নেই:

কিছুটা বিটওয়াস এবং প্রতিটি সংখ্যার বিট-বিট করে তুলনা করে একটি এ্যান্ড যোগ করে এমন একটি সংখ্যা তৈরি করতে বিটগুলির সংমিশ্রণ যেখানে place জায়গায় প্রথম বিট এবং দ্বিতীয় বিট উভয়ই সেট করা হয়েছিল। এখানে একটি "নিবললে" এবং লজিকের লজিক ম্যাট্রিক্সটি কিছুটা দিকের পরিচালনা দেখায় এবং:

  0101
& 0011
  ----
  0001 //Only the last bit is set, because only the last bit of both summands were set

আপনার ক্ষেত্রে, আমরা সংখ্যায় এমন একটি সংখ্যার সাথে তুলনা করি যা আপনি সেট দেখতে চান কেবল বিট থাকে। ধরা যাক আপনি চতুর্থ বিটটি খুঁজছেন:

  11010010
& 00001000
  --------
  00000000 //== 0, so the bit is not set

  11011010
& 00001000
  --------
  00001000 //!= 0, so the bit is set

বিট-শিফটিং, আমরা যে সংখ্যার সাথে তুলনা করতে চাই তার উত্পাদন করতে, যা ঠিক মনে হয় তা হ'ল: সংখ্যাটি নিন, বিটের সেট হিসাবে উপস্থাপন করুন এবং সেই বিটগুলি বাম বা ডানকে নির্দিষ্ট স্থানে স্থানান্তর করুন। কারণ এটি বাইনারি সংখ্যা এবং সুতরাং প্রতিটি বিট তার ডানদিকে একটির চেয়ে বড় দুটি-এর চেয়ে বড়, বামে বিট-স্থানান্তর করা প্রতিটি স্থানের জন্য একবারে সংখ্যাটি দ্বিগুণ করার সমান, সংখ্যাটি দ্বারা গুণিত করার সমান 2 ^ x আপনার উদাহরণে, চতুর্থ বিটের সন্ধানে আমরা সম্পাদন করি:

       1 (2^0) << (4-1) ==        8 (2^3)
00000001       << (4-1) == 00001000

এটি এখন কীভাবে হয়েছে, নিম্ন স্তরে কী চলছে এবং কেন এটি কাজ করে তা আপনি জানেন।


9
অনুপস্থিত বন্ধনীগুলির (অপারেটর নজরে) কারণে এই কোডটি সংকলন করে না, এটি অবশ্যই হবে var bit = (b & (1 << bitNumber-1)) != 0;
— বিটবঙ্ক

54

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


4
এটি কল্পিত তবে আমি বিশ্বাস করি জোশের সমাধানটি আরও দ্রুত এবং আরও কার্যকর।
— স্যামুয়েল অ্যালান

4
@ ব্যবহারকারী 2332868: জেআইটি সংকলক নির্দিষ্ট লাইব্রেরির ফাংশনগুলিতে বিশেষভাবে কলগুলি স্বীকৃত করে এবং কার্যকর কোড জেনারেট করে, তবে এই বিশেষ ফাংশনগুলি যদি ভালবাসা পায় তবে আমার কোনও ধারণা নেই।
— বেন ভয়েগট

4
আপনি জোশের মতো তবে খাঁটি ইনলাইন অ্যাসেমব্লিতেও একই কাজ করতে পারবেন তা নিশ্চিত হওয়া ভাল। তবে দুঃখের বিষয় আমি কেবল এনএএসএম অ্যাসেমব্লিতেই প্রোগ্রাম করি এবং অ্যাসেম্বলি সি # সম্পর্কে সংকলনগুলি সম্পর্কে জেনে নেই :(।
— স্যামুয়েল অ্যালান

4
আইএমএইচএ এটি একটি সাধারণ কাজের জন্য কর্মক্ষমতা নিহত করে। বিটওয়াস অপারেটর বিকল্প ব্যবহার করে আপনাকে এমন একটি সরঞ্জাম দেয় যা আপনি এটি প্রায় কোনও ভাষায় ব্যবহার করতে পারেন =)
— গ্যাসপা 79৯

38

এই

public static bool GetBit(this byte b, int bitNumber) {
   return (b & (1 << bitNumber)) != 0;
}

এটা করা উচিত, আমি মনে করি।


10

এটি করার আরেকটি উপায় :)

return ((b >> bitNumber) & 1) != 0;

4
এটি কাজ করবে না: বাইট বি = 1; রিটার্ন ((খ >> 1) এবং 1)! = 0 (এটি 0 এর সমান)
— রাফায়েল দিয়েগো নিকোলেটি

4
হুমমম ... আমি তোমাকে পাই না। বাইট বি = 1 হলে বিট 0 এ 1 হ'ল, (বি >> 0) & 1 দ্বারা প্রদত্ত, এবং 1 এর চেয়ে বড় বা সমান যে কোনও অবস্থানে বিট 0 (বি) এন এবং 1 দিয়ে দেওয়া যেখানে n> = 1 পাশাপাশি
— পিয়েরোজ

আমি বিশ্বাস করি না যে তিনি @ ডেভিডআান্ড্রেয়ায় মোটেও, রাফায়েল দ্বারা পোস্ট করা মন্তব্যটি ধরে নিয়েছে যে ডানদিকের সর্বাধিক বিটটি 1 বিট 1, তবে পিয়েরোজের কোডটি যখন ডানদিকের বিটটি 1 বিট হয় 0 এর জন্য, যদি বি হয় 2 হয় তবে ((2 >> 1)&1)হয় 1এবং ((2 >> 0)&1)হয় 0কারণ 200000010
— ক্যামেরন Aavik


7

বিটআরে ক্লাস ব্যবহার এবং ওপেনের পরামর্শ অনুসারে একটি এক্সটেনশন পদ্ধতি তৈরি করা:

public static bool GetBit(this byte b, int bitNumber)
{
    System.Collections.BitArray ba = new BitArray(new byte[]{b});
    return ba.Get(bitNumber);
}

11
না, দয়া করে প্রতিটি বিট পরীক্ষার জন্য একটি বিটআরে তৈরি করে ফেলে দিন না।
— বেন ভয়েগট

@ বেনভয়েগ্ট, এটি প্রতি ওপি অনুরোধের বাইটে একটি এক্সটেনশন পদ্ধতি। আপনি কোথায় বিটআরে উদাহরণ সঞ্চিত করার পরামর্শ দিচ্ছেন?
— জে ওয়াকার 7

4
আপনি অনুরোধটির বিরুদ্ধে পিছনে চাপ দিন এবং বলবেন, বাইটে কোনও পদ্ধতির মতো এটিকে ডাকবেন না, বিটআরেতে কল করুন। সম্ভবত বাইট ভেরিয়েবল সম্পূর্ণভাবে চলে যেতে পারে।
— বেন ভয়েগট

আপনি যদি সম্ভবত বাইটের নবম বিটটি পেতে চান তবে আপনি সম্ভবত সম্পাদনা খুঁজছেন এবং এটি এটি মেরে ফেলে। অন্যথায় আপনি সর্বদা অন্যান্য অপ্রয়োজনীয় জিনিস যেমন কনভার্ট করতে পারেন o টুস্ট্রিং (নাম্বার, ২) [বিট নাম্বার] এবং এটিও পেতে পারেন।
— গ্যাসপা79


4

পদ্ধতিটি হ'ল বিটওয়াসার সাথে অন্য বাইট ব্যবহার করা এবং লক্ষ্য বিটটি আটকানো।

আমি এখানে আমার ক্লাস থেকে কনভেনশন ব্যবহার করেছি যেখানে "0" সবচেয়ে উল্লেখযোগ্য বিট এবং "7" সবচেয়ে কম the

public static class ByteExtensions
{
    // Assume 0 is the MSB andd 7 is the LSB.
    public static bool GetBit(this byte byt, int index)
    {
        if (index < 0 || index > 7)
            throw new ArgumentOutOfRangeException();

        int shift = 7 - index;

        // Get a single bit in the proper position.
        byte bitMask = (byte)(1 << shift);

        // Mask out the appropriate bit.
        byte masked = (byte)(byt & bitMask);

        // If masked != 0, then the masked out bit is 1.
        // Otherwise, masked will be 0.
        return masked != 0;
    }
}

4

নীচের কোড ব্যবহার করে দেখুন। অন্যান্য পোস্টের সাথে পার্থক্য হ'ল আপনি একটি মাস্ক ( field) ব্যবহার করে একাধিক বিট সেট / করতে পারবেন । চতুর্থ বিটের মাস্কটি 1 << 3 বা 0x10 হতে পারে, উদাহরণস্বরূপ।

    public int SetBits(this int target, int field, bool value)
    {
        if (value) //set value
        {
            return target | field;
        }
        else //clear value
        {
            return target & (~field);
        }
    }

    public bool GetBits(this int target, int field)
    {
        return (target & field) > 0;
    }

** উদাহরণ **

        bool is_ok = 0x01AF.GetBits(0x10); //false
        int res = 0x01AF.SetBits(0x10, true);
        is_ok = res.GetBits(0x10);  // true

3
[Flags]
enum Relays : byte
{
    relay0 = 1 << 0,
    relay1 = 1 << 1,
    relay2 = 1 << 2,
    relay3 = 1 << 3,
    relay4 = 1 << 4,
    relay5 = 1 << 5,
    relay6 = 1 << 6,
    relay7 = 1 << 7
}

public static bool GetRelay(byte b, Relays relay)
{
    return (Relays)b.HasFlag(relay);
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.