协慌网

登录 贡献 社区

将数字除以 3 而不使用 *,/,+,-,%运算符

*/+-%运算符的情况下,如何将数字除以 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 += an = 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)的结果添加到其中。

解释其工作原理

  1. fwrite写入number字节(在上面的示例中,数字为 123456)。
  2. rewind将文件指针重设到文件的开头。
  3. fread最大的读出number “记载” 是divisor在从文件长度,并返回它读出元件的数目。

如果您写入 30 个字节,然后以 3 为单位回读文件,则将获得 10 个 “单位”。 30/3 = 10

log(pow(exp(number),0.33333333333333333333)) /* :-) */