Teilen Sie eine Zahl um 3 ohne mit *, /, +, -,% Operatoren [c]


Answers

Idiotische Bedingungen verlangen eine idiotische Lösung:

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

Wenn auch der Dezimalteil benötigt wird, deklariere das result einfach als double und füge das Ergebnis von fmod(number,divisor) .

Erläuterung, wie es funktioniert

  1. Der fwrite schreibt die number Bytes (Nummer 123456 im obigen Beispiel).
  2. rewind setzt den Dateizeiger auf die Vorderseite der Datei zurück.
  3. fread liest ein Maximum von number "Datensätze", die divisor in der Länge aus der Datei sind, und gibt die Anzahl der Elemente, die es gelesen hat.

Wenn Sie 30 Bytes schreiben dann lesen Sie die Datei in Einheiten von 3, erhalten Sie 10 "Einheiten". 30/3 = 10

Question

Wie würdest du eine Nummer um 3 teilen, ohne * , / , + , - , % , Operatoren zu benutzen?

Die Nummer darf unterschrieben oder unsigniert sein.




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



Verwenden Sie itoa , um in eine Basis 3 String zu konvertieren. Drop the last trit und konvertieren zurück zu base 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
}



Es ist auf dem Setun-Computer leicht möglich.

Um eine ganze Zahl von 3 zu teilen, schalte dich um 1 Platz nach rechts .

Ich bin mir nicht sicher, ob es strikt möglich ist, einen konformen C-Compiler auf einer solchen Plattform zu implementieren. Möglicherweise müssen wir die Regeln ein bisschen ausdehnen, wie das Interpretieren von "mindestens 8 Bits" als "in der Lage, mindestens ganze Zahlen von -128 bis +127" zu halten.




Da ist es aus Oracle, wie wäre es mit einer Nachschlagtabelle von vorberechneten Antworten. :-D




Noch eine andere lösung Dies sollte mit allen Ints (einschließlich negativer Ints) umgehen, mit Ausnahme des Minimalwertes eines int, der als hartcodierte Ausnahme behandelt werden müsste. Dies ist grundsätzlich Teilung durch Subtraktion, aber nur mit Bitoperatoren (Verschiebungen, xor, & und Komplement). Für eine schnellere Geschwindigkeit subtrahiert es 3 * (abnehmende Kräfte von 2). In c #, führt es rund 444 dieser DivideBy3 Anrufe pro Millisekunde (2,2 Sekunden für 1.000.000 teilt), also nicht schrecklich langsam, aber nein wo nahe so schnell wie ein einfaches x / 3. Im Vergleich dazu ist Coodeys schöne Lösung etwa 5 mal schneller als diese.

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

Das ist c # weil das ist, was ich praktisch hatte, aber Unterschiede von c sollte klein sein.




Die Verwendung von Zählern ist eine Grundlösung:

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

Es ist auch einfach, eine Modulfunktion durchzuführen, die Kommentare zu überprüfen.




Würde es betrügt sein, den / Operator "hinter den Kulissen" zu benutzen, indem du eval und String-Verkettung verwende?

Zum Beispiel, in Javacript, können Sie tun

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



Verwenden von BC Math in PHP :

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

MySQL (es ist ein Interview von Oracle)

> SELECT 12345 DIV 3;

Pascal :

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

x86-64 Assembler Sprache:

mov  r8, 3
xor  rdx, rdx   
mov  rax, 12345
idiv r8



Hat nicht überprüft, ob diese Antwort bereits veröffentlicht ist. Wenn das Programm auf Floating-Nummern erweitert werden muss, können die Zahlen mit 10 * multipliziert werden. Die Anzahl der benötigten Präzision und dann kann der folgende Code wieder angewendet werden.

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



int div3(int x)
{
  int reminder = abs(x);
  int result = 0;
  while(reminder >= 3)
  {
     result++;

     reminder--;
     reminder--;
     reminder--;
  }
  return result;
}






Lösung mit fma () Bibliotheksfunktion , arbeitet für jede positive Zahl:

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

Sehen Sie meine andere Antwort .




Ich denke, die richtige Antwort ist:

Warum sollte ich keinen Grundbediener benutzen, um einen Grundbetrieb zu machen?




Okay, ich denke, wir sind uns alle einig, dass dies kein echtes Weltproblem ist. Also nur zum Spaß, hier ist, wie man es mit Ada und Multithreading macht:

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;