วิธีการพิมพ์ (ใช้ cout) ตัวเลขในรูปแบบไบนารี?


215

ฉันกำลังเรียนหลักสูตรวิทยาลัยเกี่ยวกับระบบปฏิบัติการและเรากำลังเรียนรู้วิธีการแปลงจากเลขฐานสองเป็นเลขฐานสิบหก, ทศนิยมให้เป็นเลขฐานสิบหกเป็นต้นและวันนี้เราเพิ่งได้เรียนรู้วิธีการจัดเก็บหมายเลขลงนาม / ไม่ได้ลงนามในหน่วยความจำ + 1)

เรามีแบบฝึกหัดสองข้อให้ทำบนกระดาษและฉันต้องการตรวจสอบคำตอบก่อนส่งงานให้ครู ฉันเขียนโปรแกรม C ++ สำหรับแบบฝึกหัดแรก แต่ตอนนี้ฉันติดอยู่กับวิธีที่ฉันสามารถตรวจสอบคำตอบของฉันด้วยปัญหาต่อไปนี้:

char a, b;

short c;
a = -58;
c = -315;

b = a >> 3;

และเราจำเป็นต้องแสดงแทน binary ในหน่วยความจำของa, และbc

ฉันทำมันลงบนกระดาษและให้ผลลัพธ์ต่อไปนี้กับฉัน (การแทนเลขฐานสองทั้งหมดในหน่วยความจำของตัวเลขหลังจากส่วนเติมเต็มของทั้งสอง):

a = 00111010 (มันเป็นถ่านดังนั้น 1 ไบต์)

b = 00001000 (มันเป็นถ่านดังนั้น 1 ไบต์)

c = 11111110 11000101 (มันสั้นดังนั้น 2 ไบต์)

มีวิธียืนยันคำตอบของฉันหรือไม่? มีวิธีมาตรฐานใน C ++ เพื่อแสดงการเป็นตัวแทนไบนารีในหน่วยความจำของตัวเลขหรือฉันต้องรหัสแต่ละขั้นตอนด้วยตนเอง (คำนวณส่วนประกอบทั้งสองแล้วแปลงเป็นไบนารี) ฉันรู้ว่าคนหลังใช้เวลาไม่นาน แต่ฉันอยากรู้ว่ามีวิธีมาตรฐานในการทำเช่นนั้นหรือไม่


2
คุณเข้าใจการเป็นตัวแทนเลขฐานสิบหกหรือไม่ ถ้าคุณทำคุณสามารถพิมพ์การเป็นตัวแทนฐานสิบหก (โดยใช้std::hex) หุ่นยนต์ - ฉันจะปล่อยให้มันเป็นแบบฝึกหัดสำหรับคุณที่จะออกกำลังกายส่วนที่เหลือ ...
Nim

3
คุณเน้น "ในความทรงจำ" มาก แต่ฉันหวังว่าพวกเขาจะไม่ทำให้คุณจัดการกับปัญหา endian
Mark Ransom

คุณรู้หรือไม่ว่ามีความคิดเกี่ยวกับสิ่งที่ endianness คืออะไร? ถ้าคุณทำคุณสนใจเกี่ยวกับการออกกำลังกายนี้หรือไม่? คำตอบสำหรับคำถามเหล่านี้อาจมีผลต่อคำตอบสำหรับคำถามของคุณ
R. Martinho Fernandes

ขึ้นอยู่กับ IDE ของคุณหากคุณเพียงต้องการตรวจสอบความถูกต้องของโซลูชันที่เขียนด้วยมือของคุณและไม่ได้เขียนโปรแกรมเพื่อแสดงสิ่งที่มีประโยชน์คุณสามารถใช้โปรแกรมดูหน่วยความจำของ Visual Studio เพื่อดูเนื้อหาที่แน่นอนของหน่วยความจำ
Kiley Naro

1
แม้แต่ Google ก็ทำเช่นนี้ตัวอย่างเช่น"-58 ในไบนารี" - แต่ +1 สำหรับที่ต้องการหาวิธีทำด้วยตัวเองในโค้ด
Konrad Rudolph

คำตอบ:


419

วิธีที่ง่ายที่สุดน่าจะสร้าง std::bitsetcoutแทนมูลค่าแล้วสตรีมที่

#include <bitset>
...

char a = -58;    
std::bitset<8> x(a);
std::cout << x << '\n';

short c = -315;
std::bitset<16> y(c);
std::cout << y << '\n';

23
อ่าฉันลืมไปเรื่อยstd::bitsetๆ ! +1จากฉัน.
sbi

2
ขอโทษที่ฉันไม่รู้ แต่สิ่งนี้จะแสดงเฉพาะการแทนเลขฐานสองของตัวเลข (เช่น 8 จะเป็น 00001000) หรือการเป็นตัวแทนของหน่วยความจำ (เช่นวิธี -8 จะถูกเก็บไว้โดยดูแลบิตสัญลักษณ์และใช้ "ส่วนประกอบสองอย่าง") หรือไม่
Jesse Emond

12
@Jesse: bitsetอาร์กิวเมนต์ของคอนสตรัคถูกตีความว่าเป็นค่าที่ไม่ได้ลงชื่อซึ่งทำงานเหมือนกับส่วนเติมเต็มของทั้งสอง พูดอย่างเคร่งครัด C ++ ไม่รับประกันเลขคณิตส่วนเสริมของสองและการ-58 >> 3ดำเนินการในตัวอย่างของคุณจะไม่ได้กำหนด
Potatoswatter

ฉันสามารถพิมพ์ค่าบิตเซ็ต (เช่น x หรือ y ในตัวอย่างนี้) ให้เป็น char * ได้หรือไม่
nirvanaswap

1
ขอบคุณ Jerry ฉันพบ to_string นาทีต่อมา FYI การคัดเลือกไม่ทำงานตัวแปร bitset เป็นวัตถุของคลาส bitset3ul (?!) ที่ดูลึกลับจริงๆ ดีที่สุดที่จะให้ abstractions ทำงาน!
nirvanaswap

102

การใช้งานบน-the-fly std::bitsetการแปลง ไม่มีตัวแปรชั่วคราวไม่มีลูปไม่มีฟังก์ชั่นไม่มีมาโคร

Live On Coliru

#include <iostream>
#include <bitset>

int main() {
    int a = -58, b = a>>3, c = -315;

    std::cout << "a = " << std::bitset<8>(a)  << std::endl;
    std::cout << "b = " << std::bitset<8>(b)  << std::endl;
    std::cout << "c = " << std::bitset<16>(c) << std::endl;
}

พิมพ์:

a = 11000110
b = 11111000
c = 1111111011000101

6
โปรดทราบว่าไม่จำเป็นต้องใช้ขนาดการเข้ารหัส เช่นในการพิมพ์ใช้งาน:x std::cout << std::bitset<8*sizeof(x)>(x)
Apollys รองรับ Monica

25

หากคุณต้องการแสดงการเป็นตัวแทนบิตของวัตถุใด ๆ ไม่เพียง แต่เป็นจำนวนเต็มอย่าลืมตีความอีกครั้งเป็นอาร์เรย์ถ่านก่อนจากนั้นคุณสามารถพิมพ์เนื้อหาของอาร์เรย์นั้นเป็น hex หรือแม้กระทั่งเป็นไบนารี (ผ่าน bitset):

#include <iostream>
#include <bitset>
#include <climits>

template<typename T>
void show_binrep(const T& a)
{
    const char* beg = reinterpret_cast<const char*>(&a);
    const char* end = beg + sizeof(a);
    while(beg != end)
        std::cout << std::bitset<CHAR_BIT>(*beg++) << ' ';
    std::cout << '\n';
}
int main()
{
    char a, b;
    short c;
    a = -58;
    c = -315;
    b = a >> 3;
    show_binrep(a);
    show_binrep(b);
    show_binrep(c);
    float f = 3.14;
    show_binrep(f);
}

หมายเหตุว่าระบบพบมากที่สุดคือน้อย endian ดังนั้นการส่งออกของshow_binrep(c)เป็นไม่ 1111111 011000101 คุณคาดหวังเพราะนั่นไม่ใช่วิธีการที่จะเก็บไว้ในหน่วยความจำ หากคุณกำลังมองหาการแทนค่าในรูปแบบเลขฐานสองนั่นเป็นcout << bitset<16>(c)งานง่าย ๆ


11

มีวิธีมาตรฐานใน C ++ เพื่อแสดงการเป็นตัวแทนไบนารีในหน่วยความจำของตัวเลข [... ]?

ไม่ไม่std::binเช่นstd::hexหรือstd::decแต่มันก็ไม่ยากที่จะเอาท์พุทตัวเลขด้วยตัวคุณเอง:

คุณเอาท์พุทบิตซ้ายสุดโดยปิดบังส่วนที่เหลือทั้งหมด, กะซ้ายและทำซ้ำสำหรับบิตทั้งหมดที่คุณมี

(จำนวนบิตในประเภทคือsizeof(T) * CHAR_BIT)


7

เช่นเดียวกับสิ่งที่โพสต์ไปแล้วเพียงใช้ bit-shift และ mask เพื่อรับบิต ใช้งานได้สำหรับทุกประเภทเป็นแม่แบบ ( ไม่แน่ใจว่ามีวิธีมาตรฐานในการรับจำนวนบิตใน 1 ไบต์ฉันใช้ 8 ที่นี่ )

#include<iostream>
#include <climits>

template<typename T>
void printBin(const T& t){
    size_t nBytes=sizeof(T);
    char* rawPtr((char*)(&t));
    for(size_t byte=0; byte<nBytes; byte++){
        for(size_t bit=0; bit<CHAR_BIT; bit++){
            std::cout<<(((rawPtr[byte])>>bit)&1);
        }
    }
    std::cout<<std::endl;
};

int main(void){
    for(int i=0; i<50; i++){
        std::cout<<i<<": ";
        printBin(i);
    }
}

3
CHAR_BITวิธีมาตรฐานในการรับจำนวนบิตต่อไบต์เป็นแมโคร
R. Martinho Fernandes

ดูเหมือนว่า sbi จะแก้ไขโพสต์ของΕύδοξοςตามความคิดเห็นของ @ R.MartinhoFernandes อย่างไรก็ตามเขาไม่ได้เปลี่ยนประโยคสุดท้าย ฉันจะแก้ไข
gsamaras

3

ฟังก์ชั่นนำมาใช้ใหม่:

template<typename T>
static std::string toBinaryString(const T& x)
{
    std::stringstream ss;
    ss << std::bitset<sizeof(T) * 8>(x);
    return ss.str();
}

การใช้งาน:

int main(){
  uint16_t x=8;
  std::cout << toBinaryString(x);
}

ใช้ได้กับจำนวนเต็มทุกชนิด


1
#include <iostream> 
#include <cmath>       // in order to use pow() function
using namespace std; 

string show_binary(unsigned int u, int num_of_bits);

int main() 
{ 

  cout << show_binary(128, 8) << endl;   // should print 10000000
  cout << show_binary(128, 5) << endl;   // should print 00000
  cout << show_binary(128, 10) << endl;  // should print 0010000000

  return 0; 
}

string show_binary(unsigned int u, int num_of_bits) 
{ 
  string a = "";

  int t = pow(2, num_of_bits);   // t is the max number that can be represented

  for(t; t>0; t = t/2)           // t iterates through powers of 2
      if(u >= t){                // check if u can be represented by current value of t
          u -= t;
          a += "1";               // if so, add a 1
      }
      else {
          a += "0";               // if not, add a 0
      }

  return a ;                     // returns string
}

มันจะint t = pow(2, num_of_bits - 1);ไม่เป็นอย่างนั้นเหรอ?
BmyGuest

0

เมื่อใช้เวอร์ชัน C ++ เก่าคุณสามารถใช้ตัวอย่างนี้:

template<typename T>
string toBinary(const T& t)
{
  string s = "";
  int n = sizeof(T)*8;
  for(int i=n-1; i>=0; i--)
  {
    s += (t & (1 << i))?"1":"0";
  }
  return s;
}

int main()
{
  char a, b;

  short c;
  a = -58;
  c = -315;

  b = a >> 3;

  cout << "a = " << a << " => " << toBinary(a) << endl;
  cout << "b = " << b << " => " << toBinary(b) << endl;
  cout << "c = " << c << " => " << toBinary(c) << endl;
}

a = => 11000110
b = => 11111000
c = -315 => 1111111011000101

การพิมพ์จำนวนบิตที่ไม่ถูกต้อง 111 000 110 คือ 9 บิตไม่ใช่ 8
David Ledger

ฉันทำผิดขอบเขตโปรดตรวจสอบตอนนี้
Ratah

0

การใช้ std :: bitset answers และแม่แบบความสะดวกสบาย:

#include <iostream>
#include <bitset>
#include <climits>

template<typename T>
struct BinaryForm {
    BinaryForm(const T& v) : _bs(v) {}
    const std::bitset<sizeof(T)*CHAR_BIT> _bs;
};

template<typename T>
inline std::ostream& operator<<(std::ostream& os, const BinaryForm<T> bf) {
    return os << bf._bs;
}

ใช้มันแบบนี้:

auto c = 'A';
std::cout << "c: " << c << " binary: " << BinaryForm{c} << std::endl;
unsigned x = 1234;
std::cout << "x: " << x << " binary: " << BinaryForm{x} << std::endl;
int64_t z { -1024 };
std::cout << "z: " <<  << " binary: " << BinaryForm{z} << std::endl;

สร้างเอาต์พุต:

c: A binary: 01000001
x: 1234 binary: 00000000000000000000010011010010
z: -1024 binary: 1111111111111111111111111111111111111111111111111111110000000000

-5

นี่คือวิธีที่แท้จริงที่จะได้รับการแทนเลขฐานสองของตัวเลข:

unsigned int i = *(unsigned int*) &x;

ไม่; นี่แค่คัดลอก x เข้า i ถ้าคุณไม่ได้หมายถึงเรื่องนี้เป็นเรื่องตลก?
AnthonyD973

-11

นี่คือสิ่งที่คุณกำลังมองหา?

std::cout << std::hex << val << std::endl;

30
ผู้ดำเนินรายการหมายเหตุฉันพยายามที่จะกำจัดความคิดเห็นที่เป็นปฏิปักษ์หรือไม่สร้างสรรค์ภายใต้คำตอบนี้อย่างเลือกสรรและฉันจบลงด้วยการสนทนาที่ไม่สมบูรณ์ ลบความคิดเห็นทั้งหมดแล้ว โปรดแสดงความคิดเห็นอย่างมืออาชีพสร้างสรรค์และมากที่สุดในหัวข้อ หาก OP ต้องการลบสิ่งนี้ OP จะลบออกทันที หากคุณไม่เห็นด้วยกับคำตอบนี้ให้ลงคะแนน หากคุณสามารถปรับปรุงคำตอบนี้ให้แก้ไข </argument>. จริงๆแล้วพวกเราเป็นผู้ใหญ่ใช่มั้ย ฉันเกือบจะตรวจสอบทุกเพศทุกวัยที่แสดงความคิดเห็นที่นี่เพื่อให้แน่ใจว่าทุกคนมีอายุมากกว่า 13 ปี
Tim Post
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.