programing

abs 함수나 if 스테이트먼트를 사용하지 않고 절대값을 얻는다.

copyandpastes 2022. 7. 2. 21:47
반응형

abs 함수나 if 스테이트먼트를 사용하지 않고 절대값을 얻는다.

어떻게 하면 정수의 절대값을 얻을 수 있을까 생각 중이었는데if스테이트먼트도abs()처음에는 왼쪽 시프트 비트를 사용하고 있었습니다.<<음의 부호를 범위 밖으로 끌어낸 후 비트를 원래 위치로 되돌리려고 합니다만, 유감스럽게도, 저는 효과가 없습니다.왜 안 되는지 다른 방법을 알려주세요.

int abs(int v) 
{
  return v * ((v>0) - (v<0));
}

이 코드는 다음 값을 곱합니다.v와 함께-1또는1복근이 생기다.따라서 괄호 안은 다음 중 하나가 됩니다.-1또는1.

한다면v긍정적인 표현입니다.(v>0)진실이며, 가치 있는1하는 동안에(v<0)false 입니다(false의 경우 값 0).따라서 언제v긍정적이다((v>0) - (v<0)) = (1-0) = 1전체 표현은 다음과 같습니다.v * (1) == v.

한다면v이 표현은 부정적이다.(v>0)false이며, 가치가 있습니다.0하는 동안에(v<0)true(값 1)입니다.따라서, 음의 경우v,((v>0) - (v<0)) = (0-1) = -1전체 표현은 다음과 같습니다.v * (-1) == -v.

언제v == 0,둘다요.(v<0)그리고.(v>0)는 0으로 평가되며, 다음과 같이 남습니다.v * 0 == 0.

Bit Twiddle Hacks에서:

int v;           // we want to find the absolute value of v
unsigned int r;  // the result goes here 
int const mask = v >> sizeof(int) * CHAR_BIT - 1;

r = (v + mask) ^ mask;

이 코드를 C로 입력해 보면 동작합니다.

int abs(int n){
   return n*((2*n+1)%2); 
}

이 답변이 도움이 되기를 바랍니다.

브런치리스:

int abs (int n) {
    const int ret[2] = { n, -n };
    return ret [n<0];
}

주 4.7 통합 변환 / 4: [...] If the source type is bool, the value false is converted to zero and the value true is converted to one.

분기 또는 곱셈 없음:

int abs(int n) {
    int mask = n >> 31;
    return (mask & -n) | (~mask & n);
}

32비트 부호 정수(Java)를 가정하면 다음과 같이 쓸 수 있습니다.

public static int abs(int x)
{
    return (x + (x >> 31)) ^ (x >> 31);
}

곱셈도 없고, 분기도 없어요.

그건 그렇고.return (x ^ (x >> 31)) - (x >> 31);그것도 괜찮겠지만 특허가 있어요.네!

주의: 이 코드는 조건문(8bit Verison)보다 10배 이상 오래 걸릴 수 있습니다.이는 하드웨어 프로그래밍 시스템 C 등에 유용할 수 있습니다.

이건 못 봤어2개의 보완 표현과 32비트 int의 경우

( n >> 31 | 1 ) * n

왼쪽 사인 비트를 밖으로 이동시키고 오른쪽 사인 비트를 다시 제자리로 이동시키는 데는 여러 가지 이유가 있습니다(v << 1 >> 1):

  • 음수 값을 가진 부호 있는 유형을 왼쪽 이동하면 동작이 정의되지 않으므로 전혀 사용하지 않아야 합니다.
  • 가치를 부여하다unsigned원하는 효과를 얻을 수 있습니다.(unsigned)v << 1 >> 1패딩 비트가 존재하지 않는 경우 부호 비트를 삭제합니다만, 결과값은 의 절대값입니다.v오늘날에는 매우 드물지만, 부호+규모 표기를 가진 시스템에만 해당됩니다.유비쿼터스 2의 보완 아키텍처에서는 부정적인 가치를 얻을 수 있습니다.vINT_MAX+1-v

안타깝게도 Hasturkun의 솔루션에는 구현 정의 동작이 있습니다.

다음은 서명된 값에 대한 2의 보완 표현을 가진 시스템에 대해 완전히 정의된 변형입니다.

int v;           // we want to find the absolute value of v
unsigned int r;  // the result goes here 
unsigned int mask = -((unsigned int)v >> (sizeof(unsigned int) * CHAR_BIT - 1));

r = ((unsigned int)v + mask) ^ mask;

이건 어때?

#include <climits>

long abs (int n) { // we use long to avoid issues with INT MIN value as there is no positive equivalents.
    const long ret[2] = {n, -n};
    return ret[n >> (sizeof(int) * CHAR_BIT - 1)];    // we use the most significant bit to get the right index.
}

언어에서 bool이 int cast(C/C++ like)를 허용하는 경우:

float absB(float n) {
    return n - n * 2.0f * ( n < 0.0f );
}

다음을 시도해 보십시오.

int abs(int n) 
{
  return sqrt(n*n);
}

어때?

value = value > 0 ? value: ~value + 1

음수가 양수에 대한 2의 보수로 저장되고, 먼저 1의 보수를 만들고 1을 더함으로써 2의 보수를 만들 수 있다는 사실에 기초한다.

 5 ->   0000 0101b
-5 ->  (1111 1010b) + 1 -> 1111 1011b 

제가 한 일은 기본적으로 이걸 되돌리는 거였어요

-5 ->  1111 1011b
 5 -> (0000 0100b) + 1 -> 0000 0101b

조금 늦은 건 알지만 같은 문제가 생겨서 여기 도착했어요. 이게 도움이 됐으면 좋겠네요.

나눗셈(및 더 넓은 산술)을 사용하여 "if"를 형성합니다.효율적이지는 않지만, 지점은 없습니다.

int abs_via_division(int v) {
  // is_neg:0 when v >= 0
  //        1 when v < 0
  int is_neg = (int) ((4LL * v) / (4LL * v + 1));
  return  v * (1 - is_neg*2);
}

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★intlong long 넓다int with with with with , with with with with의 일반적인 |INT_MIN|.

3진 연산자를 사용합니다.

y = condition ? value_if_true : value_if_false;

사용자가 고려하는 방식으로 부호 있는 정수를 이동하는 비트는 정의되지 않은 동작이므로 옵션이 아닙니다.대신 다음과 같이 할 수 있습니다.

int abs(int n) { return n > 0 ? n : -n; }

.if문장은 그냥 조건식일 뿐이에요

또 이 있습니다.abs()논리식/조건식도 없는 경우:여기서 int는 32비트 정수라고 가정합니다..(1 - 2 * sign_bit)sign_bit = 1 / 0 to -1 / 1.

unsigned int abs_by_pure_math( int a ) {
   return (1 - (((a >> 31) & 0x1) << 1)) * a;
}

비트 시프트는 (원칙적으로) 구현 정의되지만, 보다 넓은 부호 정수 타입으로 변환하면 부호 비트가 확장됩니다.hi-bits를 정수로 해석하면 0 또는 -1이 되어 2의 보수를 반전할 수 있습니다.

int32_t abs(int32_t in)
{
  int64_t in64 = (int64_t)in;
  int32_t* ptr = (int32_t*)&in64;
  int32_t hi = *(++ptr); // assumes little-endian
  int32_t out = (in ^ hi) - hi;
  return out;
}

위의 메커니즘은 최적화가 유효하게 된 상태에서 Naigive 구현을 컴파일한 결과입니다.

mov         eax,ecx  
cdq  
xor         eax,edx  
sub         eax,edx  

언급URL : https://stackoverflow.com/questions/9772348/get-absolute-value-without-using-abs-function-nor-if-statement

반응형