음수 정수를 0으로 설정할 .NET Math 메서드를 찾고 있습니다.
수학과 개념이 비슷합니다.Abs() - 양의 정수가 주어졌을 때 동일한 정수를 반환하는 함수를 찾고 있습니다.음수가 지정되면 0을 반환합니다.
그래서:
f(3) = 3
f(0) = 0
f(-3) = 0
예, 이것은 제가 직접 작성할 수 있을 정도로 간단하지만 .NET Math 클래스에 이미 이 기능이 내장되어 있는지 아니면 몇 개의 Math를 교묘하게 연결하여 동일한 기능을 수행할 수 있는지 궁금합니다.전화요?
라고 합니다.Math.Max
:
Math.Max(0, x)
이게 당신이 원하는 것 같군요, 아닌가요?
Math.Max(0, num);
생각합니다
Math.Max(0, x)
당신이 원하는 것입니다.
지정된 32비트 부호 있는 정수num
다음 식은 음수이면 0을 반환하고, 음수이면 원래의 변경되지 않은 값을 반환합니다.
(~num >> 31) & num
이 작업을 클램핑이라고도 합니다. 0보다 작은 값은 0으로 클램프됩니다.클램핑을 적용합니다.num
다음 문장을 사용합니다.
num &= ~num >> 31;
설명.
양의 정수(및 0)만 다음 값을 갖습니다.0
가장 왼쪽에 있는 부호 비트 또는 "가장 중요한 비트"(일명 "MSB")에 해당합니다.32비트의 경우를 생각해 보겠습니다.비트 위치는 0으로 시작하는 왼쪽에서 오른쪽으로 번호가 매겨지므로 부호 비트는 "비트 31"입니다.이 비트를 뒤집은 다음 31개의 다른 비트 위치로 전파하면 다음 중 하나의 결과를 얻을 수 있습니다.
- 양의 값과 0의 경우 모든 비트가 설정됩니다(
0xFFFFFFFF
,-1
), 또는 - 음수 값의 경우 모든 비트가 지워집니다(
0x00000000
,0
).
이 결과로 원래 값을 마스킹하면 값이 원래 음수인 경우에만 0이 됩니다.
언급
부터
&
(bitwise-AND
)는 C#에서 매우 낮은 우선 순위를 가지므로 일반적으로 다음 식을 외부 괄호로 묶어야 합니다.((~num >> 31) & num)
한다면
num
서명되지 않음(예:uint ui
), 교대조가 서명되었는지 확인하려면 캐스트를 사용해야 합니다.이를 우측 산술 시프트라고 하며, MSB가 각 우측 시프트 위치에 중복되도록 합니다.((int)~ui >> 31) & ui
64비트 값의 경우 31비트가 아닌 63비트로 이동합니다.
/* signed */ long v; (~v >> 63) & v /* unsigned */ ulong ul; ((long)~ul >> 63) & ul
표시된 대로 다음을 사용해야 합니다.
~
(bitwise-NOT
) 연산자를 사용하여 부호 비트를 플립합니다."단일 빼기"를 사용하려는 경우-
대신, 당신은 가치에 대한 오답을 얻을 것입니다.0x80000000
이 값은 음수 기호를 적용해도 영향을 받지 않는 정확히 두 정수 값 중 하나이기 때문입니다.비트적으로NOT
- 반면에 모든 값의 모든 비트를 뒤집을 수 있습니다.(부정할 수 없는 다른 값은 0이며, 이 특정 문제에 대해 어느 쪽이든 올바르게 해결됩니다.)급한 경우 복사/붙여넣기가 가능한 테스트된 확장 방법이 있습니다.
public static int Clamp0(this int v) => v & ~v >> 31; public static long Clamp0(this long v) => v & ~v >> 63;
(5)의 방법을 사용할 때 한 가지 위험은 호출자가 반환 값을 할당하는 것을 잊어버린 경우 오류나 경고가 발생하지 않는다는 것입니다.C#7에서는 값 유형의 in-situ 변환을 허용하는 기준 확장 방법을 정의할 수 있습니다.이러한 방법은 반환된 것으로 선언할 수 있기 때문에 앞서 언급한 문제를 방지하는 데 도움이 됩니다.
void
:public static void RefClamp0(this ref int v) => v &= ~v >> 31; public static void RefClamp0(this ref long v) => v &= ~v >> 63; // 'void' ──^ 'ref' ──^ ^── result assigned by callee
위의 기준 연장 방법에 대한 콜 사이트 예제
int
:int x = -999; x.RefClamp0(); // CORRECT, clamps the value of 'x' in-situ; now x == 0 // x = x.RefClamp0(); // NO -- 'void' return enforces correct by-ref usage // CS0029: Cannot implicitly convert type 'void' to 'int' // -999.RefClamp0(); // NO -- compiler errors: // CS1510: A ref or out value must be an assignable variable // CS0201: Only [expressions] can be used as a statement
분기가 아닌 코드에 대해 자세히 알아봅니다!
위에 제공된 이 코드 예제는 분기 없는 코드를 보여주는 가장 간단한 비트 트위들링 예제 중 하나입니다.이 용어는 일반적으로 CPU 파이프라인의 잘못된 예측 스톨을 줄이기 위해 사용자 코드에서 조건부 분기를 최소화하는 다양한 마이크로 최적화 기술을 나타냅니다.
그것은 수학처럼 보입니다.맥스가 가는 길이지만, 이것도...;)
(num + Math.Abs(num)) / 2
수학.Max가 가장 좋지만 수학과 VB가 없습니다.
(num >= 0) * -num
언급URL : https://stackoverflow.com/questions/2509267/looking-for-net-math-method-that-will-zero-a-negative-integer
'programing' 카테고리의 다른 글
Python을 사용하여 Lovoo API 액세스 (0) | 2023.05.27 |
---|---|
Xcode 10은 com.apple.commcenter.core telephony를 손상시키는 것 같습니다.xpc (0) | 2023.05.27 |
강력한 매개 변수를 사용하여 배열을 허용하는 방법 (0) | 2023.05.22 |
스크롤 뷰어 마우스 휠이 스크롤되지 않음 (0) | 2023.05.22 |
인증서 확인 실패: 로컬 발급자 인증서를 가져올 수 없습니다. (0) | 2023.05.22 |