697

、、、、、、演算子を使用せず*/、数値を3で割るにはどうすればよいですか?+-%

番号は署名されている場合と署名されていない場合があります。

4

47 に答える 47

552

これは、目的の操作を実行する単純な関数です。ただし、演​​算子が必要なため、+あとはビット演算子を使用して値を追加するだけです。

// 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; 
}

ジムがコメントしたように、これは次の理由で機能します。

  • n = 4 * a + b
  • n / 3 = a + (a + b) / 3
  • だからsum += a、、、n = a + bそして繰り返す

  • の場合a == 0 (n < 4)sum += floor(n / 3);つまり1if n == 3, else 0

于 2012-07-27T19:51:47.083 に答える
440

ばかげた条件はばかげた解決策を必要とします:

#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;
}

小数部も必要な場合は、として宣言resultdouble、それに結果を追加しfmod(number,divisor)ます。

それがどのように機能するかの説明

  1. fwriteバイトを書き込みます(上記numberの例では、数値は123456です)。
  2. rewindファイルポインタをファイルの先頭にリセットします。
  3. freadファイルから長さのある最大のnumber「レコード」を読み取り、読み取ったdivisor要素の数を返します。

30バイトを書き込んでから、ファイルを3単位で読み戻すと、10「単位」になります。30/3 = 10

于 2012-07-27T19:55:55.640 に答える
307
log(pow(exp(number),0.33333333333333333333)) /* :-) */
于 2012-07-27T19:54:47.390 に答える
208
#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;
}
于 2012-07-27T20:01:49.597 に答える
113

(プラットフォームに依存する)インラインアセンブリを使用できます。たとえば、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;
}
于 2012-07-27T20:05:47.427 に答える
107

itoaを使用して、ベース3の文字列に変換します。最後のトリットをドロップして、ベース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
}
于 2012-07-27T19:49:39.967 に答える
57

(注:より良いバージョンについては、以下の編集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、 AndreyT0x55555556によって提案されたトリックを使用するために、同様のトリックを使用して乗算関数を簡単に実装できます。

int mul(int const x, int const y) {
  return sizeof(struct {
    char const ignore[y];
  }[x]);
}
于 2012-07-27T19:46:17.980 に答える
43

Setunコンピューターで簡単にできます。

整数を3で割るには、右に1桁シフトします。

ただし、そのようなプラットフォームに準拠するCコンパイラを実装することが厳密に可能かどうかはわかりません。「少なくとも8ビット」を「-128から+127までの少なくとも整数を保持できる」と解釈するように、ルールを少し拡張する必要があるかもしれません。

于 2012-07-27T23:07:27.380 に答える
32

これが私の解決策です:

public static int div_by_3(long a) {
    a <<= 30;
    for(int i = 2; i <= 32 ; i <<= 1) {
        a = add(a, a >> i);
    }
    return (int) (a >> 32);
}

public static long add(long a, long b) {
    long carry = (a & b) << 1;
    long sum = (a ^ b);
    return carry == 0 ? sum : add(carry, sum);
}

まず、注意してください

1/3 = 1/4 + 1/16 + 1/64 + ...

さて、残りは簡単です!

a/3 = a * 1/3  
a/3 = a * (1/4 + 1/16 + 1/64 + ...)
a/3 = a/4 + a/16 + 1/64 + ...
a/3 = a >> 2 + a >> 4 + a >> 6 + ...

今、私たちがしなければならないのは、これらのビットシフトされたaの値を足し合わせるだけです!おっと!ただし、追加することはできないため、代わりに、ビット単位の演算子を使用して追加関数を作成する必要があります。ビット単位の演算子に精通している場合、私のソリューションはかなり単純に見えるはずです...しかし、そうでない場合に備えて、最後に例を示します。

もう1つ注意すべき点は、最初に30だけ左にシフトすることです。これは、端数が四捨五入されないようにするためです。

11 + 6

1011 + 0110  
sum = 1011 ^ 0110 = 1101  
carry = (1011 & 0110) << 1 = 0010 << 1 = 0100  
Now you recurse!

1101 + 0100  
sum = 1101 ^ 0100 = 1001  
carry = (1101 & 0100) << 1 = 0100 << 1 = 1000  
Again!

1001 + 1000  
sum = 1001 ^ 1000 = 0001  
carry = (1001 & 1000) << 1 = 1000 << 1 = 10000  
One last time!

0001 + 10000
sum = 0001 ^ 10000 = 10001 = 17  
carry = (0001 & 10000) << 1 = 0

Done!

子供の頃に学んだ足し算だけです!

111
 1011
+0110
-----
10001

方程式のすべての項を追加できないため、この実装は失敗しました。

a / 3 = a/4 + a/4^2 + a/4^3 + ... + a/4^i + ... = f(a, i) + a * 1/3 * 1/4^i
f(a, i) = a/4 + a/4^2 + ... + a/4^i

div_by_3(a)= xの結果、次にx <= floor(f(a, i)) < a / 3。の場合a = 3k、間違った答えが返ってきます。

于 2012-07-27T21:33:36.633 に答える
25

32ビットの数値を3で割るには0x55555556、それを乗算してから、64ビットの結果の上位32ビットを取得します。

あとは、ビット演算とシフトを使用して乗算を実装するだけです...

于 2012-07-27T19:52:12.260 に答える
18

さらに別の解決策。これは、ハードコードされた例外として処理する必要があるintの最小値を除くすべてのint(負のintを含む)を処理する必要があります。これは基本的に減算による除算を行いますが、ビット演算子(shifts、xor、&およびcomplement)のみを使用します。より高速にするために、3 *を減算します(2の累乗を減らします)。C#では、1ミリ秒あたり約444回のDivideBy3呼び出し(1,000,000回の分割では2.2秒)を実行するため、それほど遅くはありませんが、単純なx/3ほど速くはありません。比較すると、Coodeyの優れたソリューションはこれよりも約5倍高速です。

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との違いはわずかなはずです。

于 2012-07-27T22:33:21.393 に答える
16

とても簡単です。

if (number == 0) return 0;
if (number == 1) return 0;
if (number == 2) return 0;
if (number == 3) return 1;
if (number == 4) return 1;
if (number == 5) return 1;
if (number == 6) return 2;

(もちろん、簡潔にするために一部のプログラムは省略しています。)プログラマーがこれをすべて入力するのに飽きたら、別のプログラムを作成して生成できると確信しています。私はたまたま、/彼の仕事を非常に単純化する特定の演算子を知っています。

于 2012-08-03T00:45:07.113 に答える
14

カウンターの使用は基本的な解決策です。

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
    }
}

モジュラス関数の実行も簡単です。コメントを確認してください。

于 2012-08-01T07:00:45.610 に答える
11

これは、基数2の古典的な除算アルゴリズムです。

#include <stdio.h>
#include <stdint.h>

int main()
{
  uint32_t mod3[6] = { 0,1,2,0,1,2 };
  uint32_t x = 1234567; // number to divide, and remainder at the end
  uint32_t y = 0; // result
  int bit = 31; // current bit
  printf("X=%u   X/3=%u\n",x,x/3); // the '/3' is for testing

  while (bit>0)
  {
    printf("BIT=%d  X=%u  Y=%u\n",bit,x,y);
    // decrement bit
    int h = 1; while (1) { bit ^= h; if ( bit&h ) h <<= 1; else break; }
    uint32_t r = x>>bit;  // current remainder in 0..5
    x ^= r<<bit;          // remove R bits from X
    if (r >= 3) y |= 1<<bit; // new output bit
    x |= mod3[r]<<bit;    // new remainder inserted in X
  }
  printf("Y=%u\n",y);
}
于 2012-07-28T23:48:33.287 に答える
10

Pascalでプログラムを作成し、DIV演算子を使用します。

のタグが付いているので、おそらくPascalで関数を記述し、Cプログラムから呼び出すことができます。そのための方法はシステム固有です。

ただし、FreePascalfp-compilerパッケージがインストールされているUbuntuシステムで動作する例を次に示します。(私はこれをまったく見当違いの頑固さからやっています。これが有用であるとは主張しません。)

divide_by_3.pas

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.

main.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
于 2012-07-27T19:45:36.863 に答える
8
int div3(int x)
{
  int reminder = abs(x);
  int result = 0;
  while(reminder >= 3)
  {
     result++;

     reminder--;
     reminder--;
     reminder--;
  }
  return result;
}
于 2012-08-01T06:15:07.810 に答える
7

この回答がすでに公開されているかどうかをクロスチェックしませんでした。プログラムを浮動小数点数に拡張する必要がある場合は、数値に10 *必要な精度の数値を掛けてから、次のコードを再度適用できます。

#include <stdio.h>

int main()
{
    int aNumber = 500;
    int gResult = 0;

    int aLoop = 0;

    int i = 0;
    for(i = 0; i < aNumber; i++)
    {
        if(aLoop == 3)
        {
           gResult++;
           aLoop = 0;
        }  
        aLoop++;
    }

    printf("Reulst of %d / 3 = %d", aNumber, gResult);

    return 0;
}
于 2012-07-29T10:58:00.177 に答える
7

これは、3つだけでなく、どの除数でも機能するはずです。現在、署名されていない場合のみですが、署名されたものに拡張することはそれほど難しいことではありません。

#include <stdio.h>

unsigned sub(unsigned two, unsigned one);
unsigned bitdiv(unsigned top, unsigned bot);
unsigned sub(unsigned two, unsigned one)
{
unsigned bor;
bor = one;
do      {
        one = ~two & bor;
        two ^= bor;
        bor = one<<1;
        } while (one);
return two;
}

unsigned bitdiv(unsigned top, unsigned bot)
{
unsigned result, shift;

if (!bot || top < bot) return 0;

for(shift=1;top >= (bot<<=1); shift++) {;}
bot >>= 1;

for (result=0; shift--; bot >>= 1 ) {
        result <<=1;
        if (top >= bot) {
                top = sub(top,bot);
                result |= 1;
                }
        }
return result;
}

int main(void)
{
unsigned arg,val;

for (arg=2; arg < 40; arg++) {
        val = bitdiv(arg,3);
        printf("Arg=%u Val=%u\n", arg, val);
        }
return 0;
}
于 2012-07-30T14:45:56.297 に答える
7

文字列の連結/を使用して「舞台裏」の演算子を使用するのは不正行為でしょうか?eval

たとえば、Javacriptでは、次のことができます。

function div3 (n) {
    var div = String.fromCharCode(47);
    return eval([n, div, 3].join(""));
}
于 2012-08-05T17:03:19.553 に答える
6

最初に私が思いついた。

irb(main):101:0> div3 = -> n { s = '%0' + n.to_s + 's'; (s % '').gsub('   ', ' ').size }
=> #<Proc:0x0000000205ae90@(irb):101 (lambda)>
irb(main):102:0> div3[12]
=> 4
irb(main):103:0> div3[666]
=> 222

編集:申し訳ありませんが、私はタグに気づいていませんでしたC。しかし、文字列のフォーマットについてのアイデアを使用することができます、私は推測します...

于 2012-07-27T23:51:33.317 に答える
6

PHPでのBCMathの使用:

<?php
    $a = 12345;
    $b = bcdiv($a, 3);   
?>

MySQL(Oracleからのインタビューです)

> SELECT 12345 DIV 3;

パスカル

a:= 12345;
b:= a div 3;

x86-64アセンブリ言語:

mov  r8, 3
xor  rdx, rdx   
mov  rax, 12345
idiv r8
于 2012-07-31T09:49:32.380 に答える
5

ハッカーのディライトマジックナンバー計算機の使用

int divideByThree(int num)
{
  return (fma(num, 1431655766, 0) >> 32);
}

ここで、 fmamath.hはヘッダーで定義された標準ライブラリ関数です。

于 2012-07-27T20:35:22.167 に答える
5

次のスクリプトは、演算子を使用せずに問題を解決するCプログラムを生成します* / + - %

#!/usr/bin/env python3

print('''#include <stdint.h>
#include <stdio.h>
const int32_t div_by_3(const int32_t input)
{
''')

for i in range(-2**31, 2**31):
    print('    if(input == %d) return %d;' % (i, i / 3))


print(r'''
    return 42; // impossible
}
int main()
{
    const int32_t number = 8;
    printf("%d / 3 = %d\n", number, div_by_3(number));
}
''')
于 2012-08-01T15:16:15.147 に答える
4

fma()ライブラリ関数を使用したソリューションは、任意の正の数で機能します。

#include <stdio.h>
#include <math.h>

int main()
{
    int number = 8;//Any +ve no.
    int temp = 3, result = 0;
    while(temp <= number){
        temp = fma(temp, 1, 3); //fma(a, b, c) is a library function and returns (a*b) + c.
        result = fma(result, 1, 1);
    } 
    printf("\n\n%d divided by 3 = %d\n", number, result);
}

私の別の答えを参照してください

于 2012-07-30T19:25:35.627 に答える
4

このアプローチ(c#)はどうですか?

private int dividedBy3(int n) {
        List<Object> a = new Object[n].ToList();
        List<Object> b = new List<object>();
        while (a.Count > 2) {
            a.RemoveRange(0, 3);
            b.Add(new Object());
        }
        return b.Count;
    }
于 2012-08-22T07:11:07.217 に答える
4

正しい答えは次のとおりです。

基本的な操作を行うために基本的な演算子を使用しないのはなぜですか?

于 2012-08-23T08:08:02.570 に答える
4

初め:

x/3 = (x/4) / (1-1/4)

次に、x /(1-y)を解く方法を理解します。

x/(1-1/y)
  = x * (1+y) / (1-y^2)
  = x * (1+y) * (1+y^2) / (1-y^4)
  = ...
  = x * (1+y) * (1+y^2) * (1+y^4) * ... * (1+y^(2^i)) / (1-y^(2^(i+i))
  = x * (1+y) * (1+y^2) * (1+y^4) * ... * (1+y^(2^i))

y = 1/4の場合:

int div3(int x) {
    x <<= 6;    // need more precise
    x += x>>2;  // x = x * (1+(1/2)^2)
    x += x>>4;  // x = x * (1+(1/2)^4)
    x += x>>8;  // x = x * (1+(1/2)^8)
    x += x>>16; // x = x * (1+(1/2)^16)
    return (x+1)>>8; // as (1-(1/2)^32) very near 1,
                     // we plus 1 instead of div (1-(1/2)^32)
}

を使用します+が、誰かがすでにビット単位の演算による追加を実装しています。

于 2012-08-23T11:58:21.213 に答える
3

OSXのAccelerateフレームワークの一部として含まれているcblasを使用します。

[02:31:59] [william@relativity ~]$ cat div3.c
#import <stdio.h>
#import <Accelerate/Accelerate.h>

int main() {
    float multiplicand = 123456.0;
    float multiplier = 0.333333;
    printf("%f * %f == ", multiplicand, multiplier);
    cblas_sscal(1, multiplier, &multiplicand, 1);
    printf("%f\n", multiplicand);
}

[02:32:07] [william@relativity ~]$ clang div3.c -framework Accelerate -o div3 && ./div3
123456.000000 * 0.333333 == 41151.957031
于 2012-07-29T07:34:04.523 に答える
3

一般的に、これに対する解決策は次のようになります。

log(pow(exp(numerator),pow(denominator,-1)))

于 2014-01-24T04:58:43.620 に答える
2

さて、これは現実の問題ではないことに私たちは皆同意していると思います。楽しみのために、Adaとマルチスレッドでそれを行う方法は次のとおりです。

with Ada.Text_IO;

procedure Divide_By_3 is

   protected type Divisor_Type is
      entry Poke;
      entry Finish;
   private
      entry Release;
      entry Stop_Emptying;
      Emptying : Boolean := False;
   end Divisor_Type;

   protected type Collector_Type is
      entry Poke;
      entry Finish;
   private
      Emptying : Boolean := False;
   end Collector_Type;

   task type Input is
   end Input;
   task type Output is
   end Output;

   protected body Divisor_Type is
      entry Poke when not Emptying and Stop_Emptying'Count = 0 is
      begin
         requeue Release;
      end Poke;
      entry Release when Release'Count >= 3 or Emptying is
         New_Output : access Output;
      begin
         if not Emptying then
            New_Output := new Output;
            Emptying := True;
            requeue Stop_Emptying;
         end if;
      end Release;
      entry Stop_Emptying when Release'Count = 0 is
      begin
         Emptying := False;
      end Stop_Emptying;
      entry Finish when Poke'Count = 0 and Release'Count < 3 is
      begin
         Emptying := True;
         requeue Stop_Emptying;
      end Finish;
   end Divisor_Type;

   protected body Collector_Type is
      entry Poke when Emptying is
      begin
         null;
      end Poke;
      entry Finish when True is
      begin
         Ada.Text_IO.Put_Line (Poke'Count'Img);
         Emptying := True;
      end Finish;
   end Collector_Type;

   Collector : Collector_Type;
   Divisor : Divisor_Type;

   task body Input is
   begin
      Divisor.Poke;
   end Input;

   task body Output is
   begin
      Collector.Poke;
   end Output;

   Cur_Input : access Input;

   -- Input value:
   Number : Integer := 18;
begin
   for I in 1 .. Number loop
      Cur_Input := new Input;
   end loop;
   Divisor.Finish;
   Collector.Finish;
end Divide_By_3;
于 2012-08-23T13:34:24.313 に答える
2

非常に面白かったので、一般的な区分で答えたものはありませんでした。

/* For the given integer find the position of MSB */
int find_msb_loc(unsigned int n)
{
    if (n == 0)
        return 0;

    int loc = sizeof(n)  * 8 - 1;
    while (!(n & (1 << loc)))
        loc--;
    return loc;
}


/* Assume both a and b to be positive, return a/b */
int divide_bitwise(const unsigned int a, const unsigned int b)
{
    int int_size = sizeof(unsigned int) * 8;
    int b_msb_loc = find_msb_loc(b);

    int d = 0; // dividend
    int r = 0; // reminder
    int t_a = a;
    int t_a_msb_loc = find_msb_loc(t_a);
    int t_b = b << (t_a_msb_loc - b_msb_loc);

    int i;
    for(i = t_a_msb_loc; i >= b_msb_loc; i--)  {
        if (t_a > t_b) {
            d = (d << 1) | 0x1;
            t_a -= t_b; // Not a bitwise operatiion
            t_b = t_b >> 1;
         }
        else if (t_a == t_b) {
            d = (d << 1) | 0x1;
            t_a = 0;
        }
        else { // t_a < t_b
            d = d << 1;
            t_b = t_b >> 1;
        }
    }

    r = t_a;
    printf("==> %d %d\n", d, r);
    return d;
}

回答の1つにビット単位の加算がすでに含まれているため、スキップします。

于 2012-11-16T20:18:01.363 に答える
2

すべての答えは、おそらくインタビュアーが聞きたがっていたものではありません。

私の答え:

「そんなばかげたことに誰がお金を払うのか、私は決してそうしません。誰もそれを有利にすることはありません。速くはなく、唯一のばかげています。Prozessorの設計者はそれを知っている必要がありますが、これはすべての数字で機能する必要があります。 3インチで除算する場合

于 2012-12-14T14:06:35.630 に答える
1
#include <stdio.h>

typedef struct { char a,b,c; } Triple;

unsigned long div3(Triple *v, char *r) {
  if ((long)v <= 2)  
    return (unsigned long)r;
  return div3(&v[-1], &r[1]);
}

int main() {
  unsigned long v = 21; 
  int r = div3((Triple*)v, 0); 
  printf("%ld / 3 = %d\n", v, r); 
  return 0;
}
于 2013-03-14T01:21:22.920 に答える
1

大学で学んだ定義をそのまま適用してみませんか?乗算は単なる再帰的な減算であり、減算は加算であるため、結果は非効率的ですが明確です。加算は、再帰的なxor/および論理ポートの組み合わせによって実行できます。

#include <stdio.h>

int add(int a, int b){
   int rc;
   int carry;
   rc = a ^ b; 
   carry = (a & b) << 1;
   if (rc & carry) 
      return add(rc, carry);
   else
      return rc ^ carry; 
}

int sub(int a, int b){
   return add(a, add(~b, 1)); 
}

int div( int D, int Q )
{
/* lets do only positive and then
 * add the sign at the end
 * inversion needs to be performed only for +Q/-D or -Q/+D
 */
   int result=0;
   int sign=0;
   if( D < 0 ) {
      D=sub(0,D);
      if( Q<0 )
         Q=sub(0,Q);
      else
         sign=1;
   } else {
      if( Q<0 ) {
         Q=sub(0,Q);
         sign=1;
      } 
   }
   while(D>=Q) {
      D = sub( D, Q );
      result++;
   }
/*
* Apply sign
*/
   if( sign )
      result = sub(0,result);
   return result;
}

int main( int argc, char ** argv ) 
{
    printf( "2 plus 3=%d\n", add(2,3) );
    printf( "22 div 3=%d\n", div(22,3) );
    printf( "-22 div 3=%d\n", div(-22,3) );
    printf( "-22 div -3=%d\n", div(-22,-3) );
    printf( "22 div 03=%d\n", div(22,-3) );
    return 0;
}

誰かが言うように...最初にこれを機能させます。アルゴリズムは負のQに対して機能するはずであることに注意してください...

于 2013-11-15T10:11:12.787 に答える
1

標準的な学校の除算方法を思い出し、それを2進数で行うと、3の場合、限られた値のセット(この場合は0から5)を除算して減算するだけであることがわかります。これらは、算術演算子を取り除くためにswitchステートメントで処理できます。

static unsigned lamediv3(unsigned n)
{
  unsigned result = 0, remainder = 0, mask = 0x80000000;

  // Go through all bits of n from MSB to LSB.
  for (int i = 0; i < 32; i++, mask >>= 1)
  {
    result <<= 1;
    // Shift in the next bit of n into remainder.
    remainder = remainder << 1 | !!(n & mask);

    // Divide remainder by 3, update result and remainer.
    // If remainder is less than 3, it remains intact.
    switch (remainder)
    {
    case 3:
      result |= 1;
      remainder = 0;
      break;

    case 4:
      result |= 1;
      remainder = 1;
      break;

    case 5:
      result |= 1;
      remainder = 2;
      break;
    }
  }

  return result;
}

#include <cstdio>

int main()
{
  // Verify for all possible values of a 32-bit unsigned integer.
  unsigned i = 0;

  do
  {
    unsigned d = lamediv3(i);

    if (i / 3 != d)
    {
      printf("failed for %u: %u != %u\n", i, d, i / 3);
      return 1;
    }
  }
  while (++i != 0);
}
于 2015-03-27T22:46:10.023 に答える
0

2進数で表される3の除算基準については、誰も言及していないようです。偶数桁の合計は、奇数桁の合計と等しくなければなりません(10進数の11の基準と同様)。数値が3で割り切れるかどうかを確認するで、このトリックを使用する解決策があります。

これは、MichaelBurrの編集で言及された重複の可能性があると思います。

于 2013-01-01T23:59:15.213 に答える
0
#!/bin/ruby

def div_by_3(i)
  i.div 3        # always return int http://www.ruby-doc.org/core-1.9.3/Numeric.html#method-i-div
end
于 2012-07-30T14:54:26.963 に答える
0

__div__正射投影ではないと考える場合/

def divBy3(n):
    return n.__div__(3)

print divBy3(9), 'or', 9//3
于 2012-08-21T18:02:23.900 に答える
0

2進数の3は11です。

したがって、基数2で11で(中学校のように)筆算を行うだけです。基数2では基数10よりもさらに簡単です。

最も重要なものから始まる各ビット位置について:

プレフィックスが11未満かどうかを決定します。

出力0の場合。

出力1でない場合は、適切な変更の代わりにプレフィックスビットを使用します。ケースは3つだけです。

 11xxx ->    xxx    (ie 3 - 3 = 0)
100xxx ->   1xxx    (ie 4 - 3 = 1)
101xxx ->  10xxx    (ie 5 - 3 = 2)

他のすべてのプレフィックスには到達できません。

最下位ビット位置まで繰り返し、完了します。

于 2012-08-21T18:53:53.973 に答える
0

InputValue3で割る数はどこですか

SELECT AVG(NUM) 
  FROM (SELECT InputValue NUM from sys.dual
         UNION ALL SELECT 0 from sys.dual
         UNION ALL SELECT 0 from sys.dual) divby3
于 2013-02-25T18:10:46.827 に答える
0

このコードを使用して、すべての正の非浮動小数点数を除算します。基本的に、除数ビットを左に揃えて、被除数ビットと一致させます。被除数(除数のサイズ)の各セグメントについて、被除数のセグメントが除数よりも大きいかどうかを確認するために、最初のレジストラで左にシフトしてからORを実行します。このコンセプトはもともと2004年に作成されたものです(私は信じています)。これはそのコンセプトを使用したCバージョンです。注:(少し変更しました)

int divide(int a, int b)
{
    int c = 0, r = 32, i = 32, p = a + 1;
    unsigned long int d = 0x80000000;

    while ((b & d) == 0)
    {
        d >>= 1;
        r--;
    }

    while (p > a)
    {
        c <<= 1;
        p = (b >> i--) & ((1 << r) - 1);
        if (p >= a)
            c |= 1;
    }
    return c; //p is remainder (for modulus)
}

使用例:

int n = divide( 3, 6); //outputs 2
于 2014-01-28T23:25:51.963 に答える
-1

問題を解決するために、グラフ/ツリーのような構造を使用することを考えることができます。基本的に、3で割る数と同じ数の頂点を生成します。次に、ペアになっていない各頂点を他の2つの頂点とペアリングし続けます。

大まかな擬似コード:

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

これは明らかに最適化することができ、複雑さはあなたの数の大きさによって異なりますが、++と-を実行できる場合はうまくいくはずです。クーラーだけを数えるのと同じくらい良いです。

于 2012-08-22T03:52:49.757 に答える
-1

これは、基本的に文字列比較とステートマシンを備えたPythonです。

def divide_by_3(input):
  to_do = {}
  enque_index = 0
  zero_to_9 = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
  leave_over = 0
  for left_over in (0, 1, 2):
    for digit in zero_to_9:
      # left_over, digit => enque, leave_over
      to_do[(left_over, digit)] = (zero_to_9[enque_index], leave_over)
      if leave_over == 0:
        leave_over = 1
      elif leave_over == 1:
        leave_over = 2
      elif leave_over == 2 and enque_index != 9:
        leave_over = 0
        enque_index = (1, 2, 3, 4, 5, 6, 7, 8, 9)[enque_index]
  answer_q = []
  left_over = 0
  digits = list(str(input))
  if digits[0] == "-":
    answer_q.append("-")
  digits = digits[1:]
  for digit in digits:
    enque, left_over = to_do[(left_over, int(digit))]
    if enque or len(answer_q):
      answer_q.append(enque)
  answer = 0
  if len(answer_q):
    answer = int("".join([str(a) for a in answer_q]))
  return answer
于 2012-07-30T22:29:17.920 に答える
-1

これは機能します:

smegma$ curl http://www.wolframalpha.com/input/?i=14+divided+by+3 2>/dev/null | gawk 'match($0, /link to /input/\?i=([0-9.+-]+)/, ary) { print substr( $0, ary[1, "start"], ary[1, "length"] )}' 4.6666666666666666666666666666666666666666666666666666

「14」と「3」を数字に置き換えてください。

于 2014-08-26T02:29:33.180 に答える
-2

Linuxシェルスクリプトの使用:

#include <stdio.h>
int main()
{
    int number = 30;
    char command[25];
    snprintf(command, 25, "echo $((%d %c 3)) ", number, 47);
    system( command );
    return 0;
}

私の別の答えを参照してください

于 2012-08-01T10:27:45.743 に答える
-2

良い'ol bc

$ num=1337; printf "scale=5;${num}\x2F3;\n" | bc
445.66666
于 2012-08-14T17:11:51.830 に答える
-2

これが私の祖父が子供の頃に教えてくれた方法です。+および/演算子が必要ですが、計算が簡単になります。

個々の数字を足し合わせて、3の倍数かどうかを確認します。

ただし、この方法は12を超える数値に対して機能します。

例:36、

3の倍数である3+6=9。

42、

4 + 2 = 6は、3の倍数です。

于 2012-08-21T19:39:13.027 に答える