如何将一个数除3而不使用*、/、+、-、%等运算符?
号码可以有签名,也可以没有签名。
如何将一个数除3而不使用*、/、+、-、%等运算符?
号码可以有签名,也可以没有签名。
当前回答
使用计数器是一个基本的解决方案:
int DivBy3(int num) {
int result = 0;
int counter = 0;
while (1) {
if (num == counter) //Modulus 0
return result;
counter = abs(~counter); //++counter
if (num == counter) //Modulus 1
return result;
counter = abs(~counter); //++counter
if (num == counter) //Modulus 2
return result;
counter = abs(~counter); //++counter
result = abs(~result); //++result
}
}
也很容易执行一个模数函数,查看注释。
其他回答
你可以使用(依赖于平台)内联程序集,例如,对于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;
}
用Pascal编写程序并使用DIV操作符。
因为问题被标记为c,你可以在Pascal中编写一个函数,然后在c程序中调用它;这样做的方法是特定于系统的。
但是这里有一个在我的Ubuntu系统上运行的例子,安装了Free Pascal fp-编译器包。(我这么做完全是出于不合时宜的固执;我不敢说这是有用的。)
divide_by_3。不是:
unit Divide_By_3;
interface
function div_by_3(n: integer): integer; cdecl; export;
implementation
function div_by_3(n: integer): integer; cdecl;
begin
div_by_3 := n div 3;
end;
end.
c:
#include <stdio.h>
#include <stdlib.h>
extern int div_by_3(int n);
int main(void) {
int n;
fputs("Enter a number: ", stdout);
fflush(stdout);
scanf("%d", &n);
printf("%d / 3 = %d\n", n, div_by_3(n));
return 0;
}
构建:
fpc divide_by_3.pas && gcc divide_by_3.o main.c -o main
示例执行:
$ ./main
Enter a number: 100
100 / 3 = 33
你可以考虑用图或树状结构来解决这个问题。基本上生成的顶点数与要除以3的数一样多。然后继续将每个未配对的顶点与其他两个顶点配对。
粗糙的伪代码:
function divide(int num)
while(num!=0)
Add a new vertice to vertiexList.
num--
quotient = 0
for each in vertexList(lets call this vertex A)
if vertexList not empty
Add an edge between A and another vertex(say B)
else
your Remainder is 1 and Quotient is quotient
if vertexList not empty
Add an edge between A and another vertex(say C)
else
your remainder is 2 and Quotient is quotient
quotient++
remove A, B, C from vertexList
Remainder is 0 and Quotient is quotient
这显然是可以优化的,复杂度取决于你的数字有多大,但它应该工作,只要你能做++和——。 这就像数更酷的东西一样。
愚蠢的情况需要愚蠢的解决方案:
#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,除数)的结果添加到它。
解释它是如何工作的
fwrite写入number字节(在上面的例子中number为123456)。 “倒带”将文件指针重置到文件的前面。 Fread从文件中读取长度为除数的最多数量的“记录”,并返回它所读取的元素的数量。
如果你写30个字节,然后以3为单位读回文件,你会得到10个“单位”。30 / 3 = 10
3以2为底等于11。
所以只要做长除法(就像中学那样),以2 × 11为底。以2为底比以10为底更简单。
对于从最有效位开始的每个位位:
判断prefix是否小于11。
如果它是输出0。
如果不是输出1,则替换前缀位进行适当的更改。只有三种情况:
11xxx -> xxx (ie 3 - 3 = 0)
100xxx -> 1xxx (ie 4 - 3 = 1)
101xxx -> 10xxx (ie 5 - 3 = 2)
所有其他前缀都不可达。
重复到最低位,你就完成了。