C에서 64비트 변수 선언
질문있습니다.
uint64_t var = 1; // this is 000000...00001 right?
내 암호대로라면 이렇게 될 겁니다
var ^ (1 << 43)
그러나 1이 64비트여야 한다는 것을 어떻게 알 수 있습니까?제가 대신 써야 하는 거 아닌가요?
var ^ ( (uint64_t) 1 << 43 )
하신 대로 1 입니다입니다.int
에서 2의일 것입니다 에서 2은 32입니다).입니다 43고.1<<43
두 합니다 .실,실int
됩니다.int
뿐만 아니라.
그래도 C에서 부호화된 정수 오버플로는 정의되지 않은 동작이므로 원칙적으로 어떤 일도 일어날 수 있습니다.당신의 경우, 컴파일러가 64비트 레지스터에서 그 시프트를 수행하기 위해 코드를 내보냈을 것이고, 그래서 운 좋게도 그것은 작동하는 것처럼 보입니다. 보장되고 정확한 결과를 얻으려면 당신이 작성한 두 번째 양식을 사용하거나, 또는 대안적으로 다음을 지정해야 합니다.1
…unsigned long long
그대로e를 ull
unsigned long long
최소 64비트가 보장됩니다.
var ^ ( 1ULL << 43 )
OP의 의합니다는 합니다. 상수를 계산합니다.( (uint64_t) 1 << 43 )
OP의 작은 예의 경우, 아래 2개도 동일한 성능을 발휘할 가능성이 높습니다.
uint64_t var = 1;
// OP solution)
var ^ ( (uint64_t) 1 << 43 )
// Others suggested answer
var ^ ( 1ULL << 43 )
위의 결과는 값은 같지만 유형은 다릅니다.잠재적인 차이는 C에 두 가지 유형이 존재하는 방식에 있습니다.uint64_t
그리고.unsigned long long
그리고 그 뒤에 일어날 일들.
uint64_t
정확한 범위는 0에서 2-1입니다64.
unsigned long long
범위가 0에서 최소64 2-1입니다.
한다면unsigned long long
요즘 많은 기계에 있는 것처럼 보이기 때문에 항상 64비트가 될 것입니다. 하지만 미래를 내다보고 이 코드가 다음과 같은 기계에서 실행되었다고 합시다.unsigned long long
16바이트(0에서 최소 2-1128)였습니다.
다음의 작위적인 예는 다음과 같습니다.의 첫 입니다.^
uint64_t
, 3이 됩니다.uint64_t
, 모듈로 2를64 수행하면 오버플로우가 발생하면 결과가 다음에 할당됩니다.d1
다음 의 ^
입니다.unsigned long long
그리고 3을 곱하면 제품은 2보다64 클 수 있고 그 다음에 할당됩니다.d2
.그렇게d1
그리고.d2
대답이 다릅니다
double d1, d2;
d1 = 3*(var ^ ( (uint64_t) 1 << 43 ));
d2 = 3*(var ^ ( 1ULL << 43 ));
과 함께 ,unit64_t
같이 .unit64_t
그리고.unsigned long long
같습니다.만약 당신의 대답이 a가 되는 것이 괜찮다면,unsigned long long
제 요, 한다면, 의 타입을 요.uint64_t
을 엉망으로 만드는 을 원하지 않습니다 .
var ^ ( 1ULL << 43 )
해야 합니다.
휴대용으로 사용할 수 있는 방법.unit64_t
일정한 것은 사용하는 것입니다.UINT64_C
에서)stdint.h
):
UINT64_C(1) << 43
아마도 그렇 것입니다UINT64_C(c)
됩니다와 됩니다.c ## ULL
.
C 표준부터:
.
INT
N_C(value)
다에 .int_least
N_t
.UINTN_
C(value)
다에 .uint_least
N_t
를 들어 . ,uint_least64_t
입니다의 입니다.unsigned long long int
,그리고나서UINT64_C(0x123)
할 수 .0x123ULL
.
당신의 컴파일러는 시프트가 64비트로 이루어져야 한다는 것을 모릅니다.그러나 이 특정 코드에 대한 이 특정 구성의 컴파일러의 이 특정 버전에서는 두 가지 오류가 발생합니다.그렇지 않을 거야.
를 가정하면int
는 당신의 플랫폼에서 32비트 타입입니다. (아마도 매우 가능성이 높습니다.) 두가지 오류가 있습니다.1 << 43
다음과 같습니다.
- 시프트 양이 왼쪽 피연산자 유형의 너비보다 크거나 같으면 동작이 정의되지 않습니다.
x
입니다.int
아니면unsigned int
,그리고나서x << 43
는되지 않은 .x << 32
y.x << n
n ≥ 32.예를들면1u << 43
정의되지 않은 행동도 있을 겁니다 - 왼쪽 피연산자에 서명된 유형이 있는데 작업 결과가 해당 유형에 오버플로되면 동작이 정의되지 않습니다.를 들면e
0x12345 << 16
다이기 되지 않은 .int
다에 .int
에.0x12345u << 16
다 .0x23450000u
.
"정의되지 않은 동작"은 컴파일러가 잘못된 결과를 반환하거나 충돌하는 코드를 자유롭게 생성할 수 있음을 의미합니다.이 경우 원하는 결과를 얻을 수 있습니다. 하지만 머피의 법칙에 따르면 생성된 코드는 언젠가는 원하는 대로 실행되지 않습니다.
작업이 64비트 유형에서 수행되도록 하려면 왼쪽 피연산자가 64비트 유형인지 확인해야 합니다. 결과를 할당하는 변수 유형은 중요하지 않습니다.입니다와 문제입니다.float x = 1 / 2
n을 초래하는x
데 0.5닌 0합니다. 연산자의 동작을 결정하는 데는 피연산자의 유형만 중요합니다.아무 것이나(uint64)1 << 43
아니면(long long)1 << 43
아니면(unsigned long long)1 << 43
아니면1ll << 43
아니면1ull << 43
다.서명된 유형을 사용하는 경우 오버플로가 없는 경우에만 동작이 정의되므로 오버플로 시 잘라낼 것으로 예상되는 경우 서명되지 않은 유형을 사용해야 합니다. 수 되지 않은 을 좋아하기 입니다).다. 만약 서명된 유형을 사용한다면 디버깅 목적으로 값을 출력하는 것만으로도 동작이 바뀔 수 있습니다. (컴파일러들은 정의되지 않은 동작을 이용하여 가장 효율적인 코드를 생성하는 것을 좋아하기 때문입니다. o마이크로 레벨. 레지스터 할당에 대한 압력과 같은 것에 매우 민감할 수 있습니다.
이 uint64_t
모든 을 그 , 즉이 더 합니다.따라서:
uint64_t var = 1;
… var ^ ((uint64_t)1 << 43) …
언급URL : https://stackoverflow.com/questions/19451101/declaring-64-bit-variables-in-c
'itsource' 카테고리의 다른 글
XML에서 요소와 노드의 차이점은 무엇입니까? (0) | 2023.09.24 |
---|---|
봄에 추상적="true"가 의미하는 바는 무엇입니까? (0) | 2023.09.24 |
클릭 시 다중 선택 상자의 모든 옵션을 선택하려면 어떻게 해야 합니까? (0) | 2023.09.24 |
다른 파워셸 스크립트에서 변수 로드 (0) | 2023.09.24 |
에 상당하는 주석 (0) | 2023.09.24 |