C # 이진 리터럴


187

16 진수 앞에 0x를 붙이는 것과 같이 C #에서 이진 리터럴을 작성하는 방법이 있습니까? 0b가 작동하지 않습니다.

그렇지 않은 경우 쉬운 방법은 무엇입니까? 어떤 종류의 문자열 변환?


2
상수를 사용하고 적절한 이름을 지정하면 십진수로 써야한다는 사실은 중요하지 않습니다. 개인적으로 if (a == MaskForModemIOEnabled)보다는 읽기를 원합니다if (a == 0b100101)
Lasse V. Karlsen

2
: 또 다른 참고 :이 게시물을 발견하는 경우 당신이 비트 필드를 원하기 때문에, 플래그-특성을 고려하시기 바랍니다 msdn.microsoft.com/en-us/library/cc138362.aspx#sectionToggle0
toxvaerd

17
상기 비트 필드를 정의 할 때를 제외하고는이 두 가지 좋은 조언 은 이진 리터럴로 쉽게 읽고 쓸 수 있습니다. [Flags] 열거 수량 {None = 0, One = 1, Some = 0b10, Most = 0b100, All = 0b111}
brianary

1
가치가있는 것을 위해, 바이너리 리터럴에 대한 지원 은 Roslyn에 계획되어 있습니다.
Joe White

C # 6.0에서는 여전히 지원되지 않습니다. vs2015에서 이진 리터럴을 사용할 수 없습니다 : /
anhoppe

답변:


146

C # 7.0이진 리터럴 (및 밑줄 문자를 통한 선택적 숫자 구분 기호)을 지원합니다.

예를 들면 :

int myValue = 0b0010_0110_0000_0011;

Roslyn GitHub 페이지 에서 자세한 정보를 확인할 수도 있습니다 .


3
@ D.Singh 지금 C # 7 목록에서 볼 수 있습니다. github.com/dotnet/roslyn/issues/2136
Danation

9
단! VS2017 / C # 7에서 훌륭하게 작동합니다.
STLDev

1
C #의 이진 리터럴은 빅 엔디안이지만 x86 정수에서는 리틀 엔디안이므로 혼동 Int16 = 0b0010_0110_0000_0011으로 저장됩니다 { 0b0000_0011, 0b0010_0110 }.
다이

1
@Dai는 16 진 리터럴과 다르지 않습니다. 즉, 모든 상수는 빅 엔디안이지만 인텔 / AMD 및 대부분의 ARM에는 리틀 엔디안이 저장됩니다. 0xDEADBEEF다음과 같이 저장됩니다0xEF 0xBE 0xAD 0xDE
Cole Johnson

170

최신 정보

C # 7.0에는 이제 이진 리터럴이 포함되어 있습니다.

[Flags]
enum Days
{
    None = 0,
    Sunday    = 0b0000001,
    Monday    = 0b0000010,   // 2
    Tuesday   = 0b0000100,   // 4
    Wednesday = 0b0001000,   // 8
    Thursday  = 0b0010000,   // 16
    Friday    = 0b0100000,   // etc.
    Saturday  = 0b1000000,
    Weekend = Saturday | Sunday,
    Weekdays = Monday | Tuesday | Wednesday | Thursday | Friday
}

원본 게시물

이 주제는 열거 형에서 비트 기반 플래그 값을 선언하는 것으로 보였으 므로이 종류의 편리한 트릭을 지적 할 가치가 있다고 생각했습니다. 왼쪽 시프트 연산자 ( <<)를 사용하면 비트를 특정 이진 위치로 푸시 할 수 있습니다. 이를 같은 클래스의 다른 값으로 열거 형 값을 선언하는 기능과 결합하면 비트 플래그 열거 형에 대해 매우 읽기 쉬운 선언 구문이 있습니다.

[Flags]
enum Days
{
    None        = 0,
    Sunday      = 1,
    Monday      = 1 << 1,   // 2
    Tuesday     = 1 << 2,   // 4
    Wednesday   = 1 << 3,   // 8
    Thursday    = 1 << 4,   // 16
    Friday      = 1 << 5,   // etc.
    Saturday    = 1 << 6,
    Weekend     = Saturday | Sunday,
    Weekdays    = Monday | Tuesday | Wednesday | Thursday | Friday
}

26
@ColeJohnson : 많은 개발자들이 선호합니다. 나는 일부 개발자만큼 머리에 16 진수를 변환하는 데 능숙하지 않으며 때로는 가장 낮은 공통 분모를 제공하는 것이 가장 좋습니다.
StriplingWarrior

2
열거 형이 상수로 만들어지기 때문에 이것이 가장 효과적인 방법이라고 생각합니다. 선택적 [Flags] 속성을 사용하면 비트 연산에 사용할 수 있습니다 (질문과 직접 ​​관련이 없지만 이진 리터럴을 설명 할 때 특히 유용합니다). 또 다른 흥미로운 가능성은 열거 형을 내장 유형으로 강제하는 것입니다 (이 예에서는 'Days'뒤에 ': byte'를 추가하십시오). bit.ly/MKv42E
caligari

Enum에서 0 플래그를 선언하는 것은 상당히 나쁜 습관이지만 실제로 읽기 쉽습니다.
MikeT

5
@ MikeT : 마지막 생각을 정교하게 만들거나 정교하게 연결할 수 있습니까? 값이 단순히 초기화되지 않았을 때 감지하고 실패하지 않기 때문에 종종 "1"로 시작하는 열거 형을 선언 합니다. 그러나 기본값이 실제로 의미가있는 상황이 있으며 해당 값의 이름을 추가하는 데 아무런 문제가 없을 것이라고 생각합니다.
StriplingWarrior 2016 년

3
@MikeT From ca1008 : "FlagsAttribute가 적용된 열거가 값이 0 인 멤버를 정의하는 경우, 열거에 값이 설정되지 않았 음을 나타내는 이름은 '없음'이어야합니다." 따라서 "없음"이라고하는 경우 기본값으로 사용하도록 추가하는 것이 유효합니다 . 기본적으로 초기화 된 필드의 값에 실제로 표시 할 이름이 있으면 전반적으로 더 깨끗해 보입니다.
Nyerguds

115

정수와 16 진수 만 직접 사용합니다 (ECMA 334v4).

9.4.4.2 정수 리터럴 정수 리터럴은 int, uint, long 및 ulong 유형의 값을 쓰는 데 사용됩니다. 정수 리터럴에는 10 진수와 16 진수의 두 가지 가능한 형식이 있습니다.

파싱하려면 다음을 사용할 수 있습니다.

int i = Convert.ToInt32("01101101", 2);

4
최신의 최신 정보 (2014 년 7 월)와 함께이 답변에 대한 업데이트로; C # 6.0에는 이진 리터럴이 도입되었습니다. ... wayyyyyy 아래 하단에있는 내 업데이트 된 답변을 참조하십시오
BTownTKD

1
@BTownTKD 귀하의 답변은 실제로 최고입니다.
RBT

25

열거 형의 비트 플래그에 대한 @StriplingWarrior의 답변에 덧붙여, 비트 시프트를 통해 위쪽으로 카운트하기 위해 16 진수로 사용할 수있는 쉬운 규칙이 있습니다. 1-2-4-8 순서를 사용하여 한 열을 왼쪽으로 이동 한 후 반복하십시오.

[Flags]
enum Scenery
{
  Trees   = 0x001, // 000000000001
  Grass   = 0x002, // 000000000010
  Flowers = 0x004, // 000000000100
  Cactus  = 0x008, // 000000001000
  Birds   = 0x010, // 000000010000
  Bushes  = 0x020, // 000000100000
  Shrubs  = 0x040, // 000001000000
  Trails  = 0x080, // 000010000000
  Ferns   = 0x100, // 000100000000
  Rocks   = 0x200, // 001000000000
  Animals = 0x400, // 010000000000
  Moss    = 0x800, // 100000000000
}

오른쪽 열부터 스캔하여 1-2-4-8 (shift) 1-2-4-8 (shift) 패턴을 확인하십시오.


원래 질문에 대답하기 위해 16 진수를 사용하는 @Sahuagin의 제안을 두 번째로하십시오. 이 문제를 우려하기에 충분한 이진수로 자주 작업하는 경우 16 진수를 익힐 가치가 있습니다.

소스 코드에서 이진수를 볼 필요가 있다면 위와 같이 이진 리터럴로 주석을 추가하는 것이 좋습니다.


23

다음과 같은 값을 포함하는 준 리터럴 상수를 항상 만들 수 있습니다.

const int b001 = 1;
const int b010 = 2;
const int b011 = 3;
// etc ...
Debug.Assert((b001 | b010) == b011);

자주 사용하는 경우 재사용을 위해 정적 클래스로 랩핑 할 수 있습니다.

그러나 약간의 주제를 벗어난 경우, 컴파일 시간에 알려진 비트와 관련된 의미가있는 경우 대신 Enum을 사용하는 것이 좋습니다.

enum Flags
{ 
    First = 0,
    Second = 1,
    Third = 2,
    SecondAndThird = 3
}
// later ...
Debug.Assert((Flags.Second | Flags.Third) == Flags.SecondAndThird);

18

.NET 컴파일러 플랫폼 ( "Roslyn") 의 언어 기능 구현 상태 를 살펴보면 C # 6.0에서이 기능이 계획된 기능이므로 다음 릴리스에서는 일반적인 방식으로 수행 할 수 있습니다.

이진 리터럴 상태


3
통과 되었습니까? 블로그에 올린 모든 기능이 실제로 Visual Studio 2015 릴리스를 만든 것은 아닙니다.
Colonic Panic

4
@ColonelPanic- Danation 은 "지금 C # 7 목록"에 있다고 지적합니다 -github.com/dotnet/roslyn/issues/2136
Wai Ha Lee

3
string sTable="static class BinaryTable\r\n{";
string stemp = "";
for (int i = 0; i < 256; i++)
{
stemp = System.Convert.ToString(i, 2);
while(stemp.Length<8) stemp = "0" + stemp;
sTable += "\tconst char nb" + stemp + "=" + i.ToString() + ";\r\n";
}
sTable += "}";
Clipboard.Clear();
Clipboard.SetText ( sTable);
MessageBox.Show(sTable);

이것을 사용하여 8 비트 바이너리의 경우 이것을 사용하여 정적 클래스를 만들고 클립 보드에 넣습니다. 그런 다음 프로젝트에 붙여 넣고 사용 섹션에 추가되므로 nb001010이있는 모든 것은 테이블에서 가져옵니다. 최소한 정적이지만 여전히 ... 나는 많은 PIC 그래픽 코딩에 C #을 사용하고 Hi-Tech C에서 0b101010을 많이 사용합니다.

-코드 출력 샘플-

static class BinaryTable
{   const char nb00000000=0;
    const char nb00000001=1;
    const char nb00000010=2;
    const char nb00000011=3;
    const char nb00000100=4;
//etc, etc, etc, etc, etc, etc, etc, 
}

:-) 닐


3

이진 리터럴 기능은 C # 6.0 및 Visual Studio 2015에서 구현되지 않았습니다. 그러나 2016 년 3 월 30 일 Microsoft는 이진 리터럴을 사용할 수있는 새로운 버전의 Visual Studio '15'Preview를 발표했습니다.

숫자 구분 기호에 하나 이상의 밑줄 (_) 문자를 사용할 수 있습니다. 코드 스 니펫은 다음과 같습니다.

int x           = 0b10___10_0__________________00; //binary value of 80
int SeventyFive = 0B100_________1011; //binary value of 75

WriteLine($" {x} \n {SeventyFive}");

위 코드 스 니펫에 표시된 것처럼 0b와 0B 중 하나를 사용할 수 있습니다.

숫자 구분 기호를 사용하지 않으려면 아래 코드 스 니펫과 같이 숫자 구분 기호없이 사용할 수 있습니다

int x           = 0b1010000; //binary value of 80
int SeventyFive = 0B1001011; //binary value of 75

WriteLine($" {x} \n {SeventyFive}");

2

리터럴을 사용할 수는 없지만 BitConverter 가 해결책이 될 수 있습니까?


BitConverter는 기계 엔디안이기 때문에 약간 까다로워집니다. 표준 인텔에서는 리틀 엔디안을 의미합니다. 대부분의 사람들은 리틀 엔디안 리터럴을 읽는 데 어려움을 겪고 있습니다.
Marc Gravell

1
자, 이제 나는 왜 내가 항상 알고 있었지만 BitConverter를 사용하지 않았는지 기억합니다 ...
Michael Stum

4
BitConverter에는 BitConverter.IsLittleEndian호스트 시스템이 거의없는 엔디안이 아닌 경우 테스트 및 버퍼 반전에 사용할 수 있는 필드 가 있습니다.
foxy

1

문자열 구문 분석 솔루션이 가장 인기가 있지만, 상황에 따라 문자열 구문 분석이 큰 성능 저하를 일으킬 수 있기 때문에 마음에 들지 않습니다.

일종의 비트 필드 또는 이진 마스크가 필요할 때 다음과 같이 작성하고 싶습니다.

긴 비트 마스크 = 1011001;

그리고 나중에

int bit5 = BitField.GetBit (bitMask, 5);

또는

bool flag5 = BitField.GetFlag (bitMask, 5);`

BitField 클래스가있는 곳

public static class BitField
{
    public static int GetBit(int bitField, int index)
    {
        return (bitField / (int)Math.Pow(10, index)) % 10;
    }

    public static bool GetFlag(int bitField, int index)
    {
        return GetBit(bitField, index) == 1;
    }
}

4
왝. 왜 열거 형을 사용하지 않습니까? 1-0-0-0을 의미하기 위해 ont 천을 사용하는 것은 문제를 요구합니다.
Clément

1

0b000001Visual Studio 2017 (C # 7.0)부터 사용할 수 있습니다


0

기본적으로 대답은 아니요라고 생각합니다. 쉬운 방법은 없습니다. 10 진수 또는 16 진수 상수를 사용하십시오. 간단하고 명확합니다. @RoyTinkers 답변도 좋습니다-의견을 사용하십시오.

int someHexFlag = 0x010; // 000000010000
int someDecFlag = 8;     // 000000001000

여기에있는 다른 사람들은 몇 가지 유용한 작업-라운드를 제시하지만 간단한 대답보다 나을 것이라고 생각합니다. C # 언어 디자이너는 아마도 '0b'접두어가 불필요하다고 생각했을 것입니다. HEX는 이진으로 쉽게 변환 할 수 있으며 대부분의 프로그래머는 0-8의 DEC에 해당하는 것을 알아야합니다.

또한 디버거에서 값을 검사 할 때 HEX 또는 DEC가 표시됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.