배열 위치를 얻기 위해 정수를 수정하여 루프가 순환되도록합니다. 이렇게 i %
양수를 위해 작품의 벌금을하지만 음수 모든 잘못 간다.
arrayLength
4 % 3 == 1
3 % 3 == 0
2 % 3 == 2
1 % 3 == 1
0 % 3 == 0
-1 % 3 == -1
-2 % 3 == -2
-3 % 3 == 0
-4 % 3 == -1
그래서 나는 구현이 필요하다
int GetArrayIndex(int i, int arrayLength)
그런
GetArrayIndex( 4, 3) == 1
GetArrayIndex( 3, 3) == 0
GetArrayIndex( 2, 3) == 2
GetArrayIndex( 1, 3) == 1
GetArrayIndex( 0, 3) == 0
GetArrayIndex(-1, 3) == 2
GetArrayIndex(-2, 3) == 1
GetArrayIndex(-3, 3) == 0
GetArrayIndex(-4, 3) == 2
나는 전에 이것을했지만 어떤 이유로 든 오늘 내 두뇌가 녹고있다 🙁
답변
나는 항상 내 자신의 mod
기능을 사용합니다.
int mod(int x, int m) {
return (x%m + m)%m;
}
물론, 모듈러스 연산 에 대한 두 번의 호출이 걱정된다면 , 다음과 같이 쓸 수 있습니다.
int mod(int x, int m) {
int r = x%m;
return r<0 ? r+m : r;
}
또는 이의 변형.
작동하는 이유는 “x % m”이 항상 [-m + 1, m-1] 범위에 있기 때문입니다. 따라서 음수이면 m을 추가하면 값 modulo m을 변경하지 않고 양수 범위에 놓입니다.
답변
C #과 C ++의 % 연산자는 실제로 모듈로가 아니며 나머지입니다. 원하는 경우 모듈로의 공식은 다음과 같습니다.
float nfmod(float a,float b)
{
return a - b * floor(a / b);
}
이것을 C # (또는 C ++)으로 다시 코딩해야하지만 나머지가 아닌 모듈로를 얻는 방법입니다.
답변
%
한 번만 사용하는 단일 라인 구현 :
int mod(int k, int n) { return ((k %= n) < 0) ? k+n : k; }
답변
부정적인 배당 / 제수를 설명하는 경우 “if (m <0) m = -m;”을 추가하더라도 ShreevatsaR의 답변은 모든 경우에 적용되지 않습니다.
예를 들어, -12 mod -10은 8이고 -2 여야합니다.
다음 구현은 양수 및 음수 배당 / 제수 모두에 대해 작동하며 다른 구현 (즉, Java, Python, Ruby, Scala, Scheme, Javascript 및 Google 계산기)을 준수합니다.
internal static class IntExtensions
{
internal static int Mod(this int a, int n)
{
if (n == 0)
throw new ArgumentOutOfRangeException("n", "(a mod 0) is undefined.");
//puts a in the [-n+1, n-1] range using the remainder operator
int remainder = a%n;
//if the remainder is less than zero, add n to put it in the [0, n-1] range if n is positive
//if the remainder is greater than zero, add n to put it in the [n-1, 0] range if n is negative
if ((n > 0 && remainder < 0) ||
(n < 0 && remainder > 0))
return remainder + n;
return remainder;
}
}
xUnit을 사용한 테스트 스위트 :
[Theory]
[PropertyData("GetTestData")]
public void Mod_ReturnsCorrectModulo(int dividend, int divisor, int expectedMod)
{
Assert.Equal(expectedMod, dividend.Mod(divisor));
}
[Fact]
public void Mod_ThrowsException_IfDivisorIsZero()
{
Assert.Throws<ArgumentOutOfRangeException>(() => 1.Mod(0));
}
public static IEnumerable<object[]> GetTestData
{
get
{
yield return new object[] {1, 1, 0};
yield return new object[] {0, 1, 0};
yield return new object[] {2, 10, 2};
yield return new object[] {12, 10, 2};
yield return new object[] {22, 10, 2};
yield return new object[] {-2, 10, 8};
yield return new object[] {-12, 10, 8};
yield return new object[] {-22, 10, 8};
yield return new object[] { 2, -10, -8 };
yield return new object[] { 12, -10, -8 };
yield return new object[] { 22, -10, -8 };
yield return new object[] { -2, -10, -2 };
yield return new object[] { -12, -10, -2 };
yield return new object[] { -22, -10, -2 };
}
}
답변
이해력 향상.
으로 유클리드의 정의 유행의 결과는 항상 양수 여야합니다.
전의:
int n = 5;
int x = -3;
int mod(int n, int x)
{
return ((n%x)+x)%x;
}
산출:
-1
답변
두 가지 주요 답변 비교
(x%m + m)%m;
과
int r = x%m;
return r<0 ? r+m : r;
실제로 첫 번째 것은 OverflowException
잠시 동안 던질 수 있고 두 번째는 그렇지 않을 것이라는 사실을 언급 한 사람은 없습니다. 더 나쁜 것은 기본 확인되지 않은 컨텍스트를 사용하면 첫 번째 답변이 잘못된 답변을 반환 할 수 있습니다 ( mod(int.MaxValue - 1, int.MaxValue)
예 : 참조 ). 따라서 두 번째 대답은 더 빠를뿐만 아니라 더 정확한 것처럼 보입니다.
답변
모듈러스 (arrayLength)를 %의 음수 결과에 추가하기 만하면됩니다.