어떻게 사용하지 않고 3으로 번호를 나누는 것 *
, /
, +
, -
, %
, 연산자?
숫자는 부호가 있거나 부호가 없을 수 있습니다.
답변
원하는 작업을 수행 하는 간단한 기능 입니다. 그러나 +
연산자 가 필요 하므로 비트 연산자로 값을 추가하기 만하면됩니다.
// replaces the + operator
int add(int x, int y)
{
while (x) {
int t = (x & y) << 1;
y ^= x;
x = t;
}
return y;
}
int divideby3(int num)
{
int sum = 0;
while (num > 3) {
sum = add(num >> 2, sum);
num = add(num >> 2, num & 3);
}
if (num == 3)
sum = add(sum, 1);
return sum;
}
Jim은 다음과 같은 이유로이 작업을 설명했습니다.
n = 4 * a + b
n / 3 = a + (a + b) / 3
-
그래서
sum += a
,n = a + b
그리고 반복 -
언제
a == 0 (n < 4)
,sum += floor(n / 3);
즉 1,if n == 3, else 0
답변
이디 오 상태는 이디 오 솔루션을 요구합니다.
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE * fp=fopen("temp.dat","w+b");
int number=12346;
int divisor=3;
char * buf = calloc(number,1);
fwrite(buf,number,1,fp);
rewind(fp);
int result=fread(buf,divisor,number,fp);
printf("%d / %d = %d", number, divisor, result);
free(buf);
fclose(fp);
return 0;
}
소수 부분이 필요 또한, 그냥 선언 result
으로 double
하고 여기에 결과를 추가합니다 fmod(number,divisor)
.
작동 방식에 대한 설명
fwrite
쓰기 용number
바이트 (숫자는 상기 예에서 123456이다).rewind
파일 포인터를 파일 앞쪽으로 재설정합니다.fread
파일에서 길이number
가 최대 인 “레코드”를divisor
읽고 읽은 요소 수를 반환합니다.
30 바이트를 쓴 다음 3 단위로 파일을 다시 읽으면 10 개의 “단위”가 표시됩니다. 30/3 = 10
답변
log(pow(exp(number),0.33333333333333333333)) /* :-) */
답변
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int num = 1234567;
int den = 3;
div_t r = div(num,den); // div() is a standard C function.
printf("%d\n", r.quot);
return 0;
}
답변
예를 들어 x86의 경우 (플랫폼 종속) 인라인 어셈블리를 사용할 수 있습니다. (음수에도 적용됨)
#include <stdio.h>
int main() {
int dividend = -42, divisor = 5, quotient, remainder;
__asm__ ( "cdq; idivl %%ebx;"
: "=a" (quotient), "=d" (remainder)
: "a" (dividend), "b" (divisor)
: );
printf("%i / %i = %i, remainder: %i\n", dividend, divisor, quotient, remainder);
return 0;
}
답변
itoa 를 사용하여 밑줄 3 문자열로 변환 하십시오 . 마지막 trit를 버리고 base 10으로 다시 변환하십시오.
// Note: itoa is non-standard but actual implementations
// don't seem to handle negative when base != 10.
int div3(int i) {
char str[42];
sprintf(str, "%d", INT_MIN); // Put minus sign at str[0]
if (i>0) // Remove sign if positive
str[0] = ' ';
itoa(abs(i), &str[1], 3); // Put ternary absolute value starting at str[1]
str[strlen(&str[1])] = '\0'; // Drop last digit
return strtol(str, NULL, 3); // Read back result
}
답변
(참고 : 더 나은 버전을 보려면 아래 편집 2를 참조하십시오!)
“[..] +
[..] 연산자 를 사용하지 않고”라고 말했기 때문에이 방법은 까다 롭지 않습니다 . +
문자를 함께 사용하는 것을 금지하려면 아래를 참조하십시오 .
unsigned div_by(unsigned const x, unsigned const by) {
unsigned floor = 0;
for (unsigned cmp = 0, r = 0; cmp <= x;) {
for (unsigned i = 0; i < by; i++)
cmp++; // that's not the + operator!
floor = r;
r++; // neither is this.
}
return floor;
}
그럼 그냥 말을 div_by(100,3)
나누기에 100
의해 3
.
편집 : 계속해서 ++
연산자를 교체 할 수 있습니다 .
unsigned inc(unsigned x) {
for (unsigned mask = 1; mask; mask <<= 1) {
if (mask & x)
x &= ~mask;
else
return x & mask;
}
return 0; // overflow (note that both x and mask are 0 here)
}
편집 2 : 포함 된 연산자 사용하지 않고 약간 빠른 버전 +
, -
, *
, /
, %
자 .
unsigned add(char const zero[], unsigned const x, unsigned const y) {
// this exploits that &foo[bar] == foo+bar if foo is of type char*
return (int)(uintptr_t)(&((&zero[x])[y]));
}
unsigned div_by(unsigned const x, unsigned const by) {
unsigned floor = 0;
for (unsigned cmp = 0, r = 0; cmp <= x;) {
cmp = add(0,cmp,by);
floor = r;
r = add(0,r,1);
}
return floor;
}
구문 이 동일한 함수 매개 변수 목록을 제외하고 add
는 *
문자 를 사용하지 않고 포인터 유형을 표시 할 수 없으므로 함수 의 첫 번째 인수를 사용합니다 .type[]
type* const
FWIW, AndreyT가0x55555556
제안한 트릭을 사용하기 위해 비슷한 트릭을 사용하여 곱셈 함수를 쉽게 구현할 수 있습니다 .
int mul(int const x, int const y) {
return sizeof(struct {
char const ignore[y];
}[x]);
}