如何将一个数除3而不使用*、/、+、-、%等运算符?
号码可以有签名,也可以没有签名。
如何将一个数除3而不使用*、/、+、-、%等运算符?
号码可以有签名,也可以没有签名。
当前回答
用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
其他回答
一般来说,解决这个问题的方法是:
log(pow(exp(numerator),pow(deliminator,-1)))
Yet another solution. This should handle all ints (including negative ints) except the min value of an int, which would need to be handled as a hard coded exception. This basically does division by subtraction but only using bit operators (shifts, xor, & and complement). For faster speed, it subtracts 3 * (decreasing powers of 2). In c#, it executes around 444 of these DivideBy3 calls per millisecond (2.2 seconds for 1,000,000 divides), so not horrendously slow, but no where near as fast as a simple x/3. By comparison, Coodey's nice solution is about 5 times faster than this one.
public static int DivideBy3(int a) {
bool negative = a < 0;
if (negative) a = Negate(a);
int result;
int sub = 3 << 29;
int threes = 1 << 29;
result = 0;
while (threes > 0) {
if (a >= sub) {
a = Add(a, Negate(sub));
result = Add(result, threes);
}
sub >>= 1;
threes >>= 1;
}
if (negative) result = Negate(result);
return result;
}
public static int Negate(int a) {
return Add(~a, 1);
}
public static int Add(int a, int b) {
int x = 0;
x = a ^ b;
while ((a & b) != 0) {
b = (a & b) << 1;
a = x;
x = a ^ b;
}
return x;
}
这是c#,因为这是我手边的东西,但与c的区别应该很小。
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)
所有其他前缀都不可达。
重复到最低位,你就完成了。
使用黑客的喜悦魔术数字计算器
int divideByThree(int num)
{
return (fma(num, 1431655766, 0) >> 32);
}
其中fma是在math.h头文件中定义的标准库函数。
通过使用eval和字符串连接来在“幕后”使用/操作符是欺骗吗?
例如,在Javacript中,您可以这样做
function div3 (n) {
var div = String.fromCharCode(47);
return eval([n, div, 3].join(""));
}