web-gelistirme-sc.com

*, /, +, -,% operatörleri kullanmadan bir sayıyı 3'e bölün

*, /, +, -, %, operatörleri kullanmadan bir sayıyı 3'e nasıl bölerdiniz?

Numara imzalanmış veya imzasız olabilir.

672
Green goblin

Bu bir basit işlev istenen işlemi gerçekleştirir. Ancak + işlecini gerektirir, bu nedenle yapmanız gereken tek şey bit işleçleriyle değerleri eklemektir:

// 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'in bu eserlere yorum yaptığı gibi:

  • n = 4 * a + b
  • n / 3 = a + (a + b) / 3
  • Yani sum += a, n = a + b ve yinelenen

  • a == 0 (n < 4), sum += floor(n / 3);, yani 1, if n == 3, else 0

542
qwertz

Aptalca koşullar aptalca bir çözüm gerektirir:

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

Ondalık kısım gerekliyse, result öğesini double olarak bildirin ve ona fmod(number,divisor) sonucunu ekleyin.

Nasıl çalıştığını açıklama

  1. fwritenumber baytını yazar (yukarıdaki örnekte 123456 olan).
  2. rewind, dosya işaretçisini dosyanın önüne sıfırlar.
  3. fread, dosyadaki number uzunluğundaki maksimum divisor "kayıtlarını" okur ve okuduğu öğe sayısını döndürür.

Eğer 30 byte yazarsanız, dosyayı 3 birim halinde tekrar okursanız, 10 birim alırsınız. 30/3 = 10

434
Matteo Italia
log(pow(exp(number),0.33333333333333333333)) /* :-) */
306
Alan Curry
#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;
}
203
nos

(Platforma bağlı) satır içi derleme, örneğin x86 için kullanabilirsiniz: (ayrıca negatif sayılar için de çalışır)

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

Temel 3 dizeye dönüştürmek için itoa kullanın. Sonuncuyu bırak trit ve üs 10'a dön.

// 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
}
105
Bo Lu

(not: daha iyi bir sürüm için aşağıdaki Düzenleme 2'ye bakın!)

Bu göründüğü kadar zor değil, çünkü "[..] + [..] operatörlerini kullanmadan " dedin. + karakterini hep birlikte kullanmayı yasaklamak istiyorsanız aşağıya bakın.

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

daha sonra 100 ile 3 öğesini bölmek için div_by(100,3) deyin.


Düzen : Devam edebilir ve ++ operatörünü de değiştirebilirsiniz:

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

Düzenleme 2: +, -, *, /, % karakterleri içeren herhangi bir operatör kullanmadan biraz daha hızlı sürüm.

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 işlevinin ilk argümanını kullanırız, çünkü * karakterini kullanmadan işaretçi türünü gösteremiyoruz, işlev parametre listeleri dışında, type[] sözdiziminin type* const ile aynı olduğu yerlerde.

FWIW, AndreyT tarafından önerilen 0x55555556 numarasını kullanmak için benzer bir numara kullanarak çarpma işlevini kolayca uygulayabilirsiniz:

int mul(int const x, int const y) {
  return sizeof(struct {
    char const ignore[y];
  }[x]);
}
57
bitmask

Setun bilgisayar üzerinde kolayca mümkündür.

Bir tamsayıyı 3'e bölmek için 1 yere sağa kaydır .

Yine de böyle bir platformda uygun bir C derleyicisi uygulamanın kesinlikle mümkün olup olmadığından emin değilim. Kuralları biraz uzatmalıyız, "en az 8 bit" i "en az -128 ile +127 arasında en az tam sayı tutabilen" olarak yorumlamak gibi.

45
Mechanical snail

Oracle’dan beri, önceden hesaplanmış cevapların aranması tablosuna ne dersiniz? :-D

33
Jeff Martin

İşte benim çözümüm:

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

İlk önce, not al

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

Şimdi, gerisi basit!

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 + ...

Şimdi tek yapmamız gereken, bu bit kaydırılmış değerleri bir! Hata! Yine de ekleyemiyoruz, bu yüzden bit-wise operatörleri kullanarak bir ekleme fonksiyonu yazmak zorundayız! Bit-bilge operatörlere aşina iseniz, benim çözümüm oldukça basit görünmeli ... ama tam olarak yapmamanız durumunda, sonunda bir örnek üzerinden geçeceğim.

Unutulmaması gereken başka bir şey, ilk önce 30 sola kayıyorum! Bu, kesirlerin yuvarlanmadığından emin olmak içindir.

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!

Çocukken öğrendiğin bir şey var!

111
 1011
+0110
-----
10001

Bu uygulama başarısız çünkü denklemin tüm terimlerini ekleyemiyoruz:

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

Varsayalım ki div_by_3(a) = x, ardından x <= floor(f(a, i)) < a / 3. a = 3k olduğunda, yanlış cevap alırız.

32
tschultz

32 bitlik bir sayıyı 3'e bölmek için, biri 0x55555556 ile çarpabilir ve sonra 64 bitlik sonucun üst 32 bitini alabilir.

Şimdi yapılacak tek şey bit işlemleri ve vardiya kullanarak çarpma uygulamak ...

25
AnT

Yine başka bir çözüm. Bu, zor kodlanmış bir istisna olarak ele alınması gereken bir int'nin min değeri dışındaki tüm girişleri (negatif girişler dahil) ele almalıdır. Bu temelde çıkarma işlemiyle bölme yapar, ancak yalnızca bit işleçlerini kullanır (shift, xor ve & complement). Daha yüksek hız için, 3 * 'ı (2'nin azalan gücü) çıkarır. C # 'da, bu DivideBy3 çağrılarının yaklaşık 444'ü milisaniye başına (1.000.000 bölme için 2.2 saniye) yürütür, bu yüzden korkunç derecede yavaş değil, basit bir x/3 kadar hızlı değil. Buna karşılık, Coodey's Nice çözümü, bundan yaklaşık 5 kat daha hızlı.

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

Bu c # çünkü elimde kullanışlı olan şeydi, ama c'den farklı olması çok küçük olmalı.

18
hatchet

Gerçekten çok kolay.

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;

(Tabii ki, kısalık uğruna programın bir kısmını ihmal ettim.) Eğer programcı bütün bunları yazmaktan yorulursa, onun için oluşturmak için ayrı bir program yazabileceğinden eminim. İşini çok kolaylaştıracak belli bir operatör, /, farkındayım.

15
thedayturns

Sayaçları kullanmak temel bir çözümdür:

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

Bir modül fonksiyonu gerçekleştirmek kolaydır, yorumları kontrol edin.

14
GJ.

Bu, temel 2'deki klasik bölme algoritmasıdır:

#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);
}
11
Eric Bainville

Programı Pascal'a yazın ve DIV operatörünü kullanın.

Soru c olarak etiketlendiğinden, Pascal'da bir işlev yazabilir ve C programınızdan arayabilirsiniz; Bunu yapma yöntemi sisteme özgüdür.

Ama işte Ubuntu sistemimde Ücretsiz Pascal fp-compiler paketi kurulu olarak çalışan bir örnek. (Bunu, yanlış yerleştirilmiş inatçılığın dışında yapıyorum; bunun faydalı olduğunu iddia etmiyorum.)

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

Derlemek için:

fpc divide_by_3.pas && gcc divide_by_3.o main.c -o main

Örnek yürütme:

$ ./main
Enter a number: 100
100 / 3 = 33
9
Keith Thompson
int div3(int x)
{
  int reminder = abs(x);
  int result = 0;
  while(reminder >= 3)
  {
     result++;

     reminder--;
     reminder--;
     reminder--;
  }
  return result;
}
8
Amir Saniyan

Bu cevabın daha önce yayınlanmış olup olmadığını kontrol etmedim. Programın değişken sayılara uzatılması gerekiyorsa, sayılar gereken 10 * hassasiyet sayısı ile çarpılabilir ve daha sonra aşağıdaki kod tekrar uygulanabilir.

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

BC Math in PHP kullanarak:

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

MySQL (Oracle’ın bir röportajı)

> SELECT 12345 DIV 3;

Pascal :

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

x86-64 Assembly dili:

mov  r8, 3
xor  rdx, rdx   
mov  rax, 12345
idiv r8
7
Pedro L.

Bu sadece üç değil, herhangi bir bölen için çalışmalıdır. Şu anda yalnızca imzasızlar için, ancak imzalı alana genişletmek o kadar zor olmamalı.

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

/ işlecini eval ve string birleştirme kullanarak "perde arkasında" kullanmak hile yapmak olur mu?

Örneğin, Javacript'te

function div3 (n) {
    var div = String.fromCharCode(47);
    return eval([n, div, 3].join(""));
}
7
Peter Olson

İlk önce geldim.

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

EDIT: Üzgünüz, C etiketini fark etmedim. Fakat string formatlama fikrini kullanabilirsin, sanırım ...

6
defhlt

Aşağıdaki script, * / + - % işleçlerini kullanmadan sorunu çözen bir C programı oluşturur:

#!/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));
}
''')
5
Mechanical snail

Hacker'ın Delight Magic numarası hesaplayıcısının kullanılması

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

Burada fma , math.h başlığında tanımlanan standart bir kütüphane işlevidir.

5
Jainendra

Bence doğru cevap:

Temel bir işlem yapmak için neden temel bir operatör kullanmıyorum?

4
Gregoire

fma () library işlevi kullanarak çözüm, herhangi bir pozitif sayı için çalışır:

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

Başka bir cevabımı görün .

4
Eight

Peki ya bu yaklaşım (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;
    }
4
mclafee

OS X'in Accelerate çerçevesinin bir parçası olarak dahil cblas kullanın.

[02:31:59] [[email protected] ~]$ 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] [[email protected] ~]$ clang div3.c -framework Accelerate -o div3 && ./div3
123456.000000 * 0.333333 == 41151.957031
3
wjl

İlk:

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

Sonra x/(1 - y) 'nin nasıl çözüleceğini çözün:

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 ile:

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

Her ne kadar + kullanıyor olsa da, birisi zaten bit yönünde op ekledi.

3
Zang MingJie

Tüm cevaplar muhtemelen görüşmecinin duymak istediği şey değildir:

Cevabım:

“Böyle aptalca şeyler için para ödeyecek kimseyi asla yapmam. Bu konuda kimsenin bir avantajı olmayacak, daha hızlı değil, sadece aptalca. Prozessor tasarımcıları bunu bilmek zorunda, ama bu daha sonra tüm sayılar için çalışmalı, sadece 3'e bölünmek için "

2
AlexWien

Tamam, bunun gerçek bir dünya sorunu olmadığı konusunda hepimizin hemfikir olduğunu düşünüyorum. Yani sadece eğlence için, işte Ada ve çoklu okuma ile nasıl yapacağınız:

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;
2
flyx

Çok eğlendik hiçbiri genel bir bölümle cevap vermedi:

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

Bitsel ekleme zaten cevaplardan birinde verilmiştir, bu yüzden atlamak için.

2
Xolve

Genel olarak, buna bir çözüm olacaktır:

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

1
Gaurav Narang

Neden sadece üniversitede okuyan tanımı uygulamıyoruz? Sonuç, verimsiz olabilir ancak açıktır, çünkü çarpma sadece özyinelemeli çıkarma ve çıkarma bir toplamadır, o zaman ekleme, özyinelemeli xor/ve mantık portu kombinasyonu ile gerçekleştirilebilir.

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

Birinin dediği gibi ... önce bu işi yap. Algoritma negatif Q için çalışması gerektiğini unutmayın ...

1
Jekyll
#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;
}
1
perreal

Standart okul bölme yöntemini kendinize hatırlatır ve ikili olarak yaparsanız, 3 durumunda sınırlı bir değer kümesini (bu durumda 0'dan 5'e) bölüp çıkardığınızı keşfedeceksiniz. Bunlar, aritmetik operatörlerden kurtulmak için bir switch ifadesiyle ele alınabilir.

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);
}
1
kyku

InputValue, 3'e bölünecek sayıdır.

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
1
Craig

Bu çalışacak:

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

Numaralarınızla '14' ve '3' yerine yazınız.

0
CPRitter

Taban 2'deki 3, 11'dir.

Bu yüzden sadece 2 ile 11 arasındaki uzun bölümleri (ortaokuldaki gibi) 11 ile yapın.

En önemli ile başlayan her bit pozisyonu için:

Önekin 11'den küçük olup olmadığına karar verin.

0 çıkışlıysa.

Çıktı 1 değilse ve ardından uygun değişiklik için önek bitlerini kullanın. Sadece üç vaka var:

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

Diğer tüm öneklere erişilemiyor.

En düşük bit pozisyonuna kadar tekrarlayın ve bitirdiniz.

0
Andrew Tomazos

Bu kodu tüm pozitif, değişken olmayan sayıları bölmek için kullanırdım. Temel olarak bölen bitlerini eşleştirmek için bölen bitlerini sola hizalamak istiyorsunuz. Temettülün her bir bölümü (bölenin büyüklüğü) için, temettü bölümünün bölenden daha büyük olup olmadığından emin olmak için kontrol etmek istediğinizde, daha sonra ilk kayıt memurunda Sola Kaydır ve ardından OR seçeneğinden emin olun. Bu konsept aslında 2004'te yaratıldı (standford'a inanıyorum), İşte bu konsepti kullanan bir C versiyonu. Not: (Biraz değiştirdim)

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

Örnek Kullanım:

int n = divide( 3, 6); //outputs 2
0
MysteryDev

__div__ yazısının ortografik olarak olmadığını düşünürsek /

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

print divBy3(9), 'or', 9//3
0
user1125394

İkili olarak temsil edilen 3 bölüm kriterinin bahsi geçen hiç kimse gibi görünmüyor - çift hanelerin toplamı bile, tek hanelerin toplamına eşit olmalıdır (ondalıkta 11'in kriterine benzer). Bu hileyi kullanan çözümler altında bir sayının 3'e bölünebilir olup olmadığını kontrol edin .

Sanırım bu Michael Burr'ın düzenlemesinin bahsettiği olası kopya.

0
yoniLavi
#!/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
0
A B