Comment diviseriez-vous un nombre par 3 sans utiliser les opérateurs *
, /
, +
, -
, %
?
Le numéro peut être signé ou non signé.
Ceci est un fonction simple qui effectue l'opération souhaitée. Mais cela nécessite l'opérateur +
, il ne vous reste donc qu'à ajouter les valeurs avec des opérateurs de bits:
// 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;
}
Comme Jim a commenté cela fonctionne, parce que:
n = 4 * a + b
n / 3 = a + (a + b) / 3
Donc, sum += a
, n = a + b
, et itérer
Lorsque a == 0 (n < 4)
, sum += floor(n / 3);
, c'est-à-dire 1, if n == 3, else 0
Les conditions idiotes appellent une solution idiote:
#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;
}
Si la partie décimale est également nécessaire, déclarez simplement result
comme double
et ajoutez-y le résultat de fmod(number,divisor)
.
Explication du fonctionnement
fwrite
écrit number
octets (le nombre étant 123456 dans l'exemple ci-dessus).rewind
réinitialise le pointeur de fichier à l'avant du fichier.fread
lit un maximum de number
"enregistrements" d'une longueur de divisor
à partir du fichier et renvoie le nombre d'éléments lus.Si vous écrivez 30 octets puis relisez le fichier par unités de 3, vous obtenez 10 "unités". 30/3 = 10
log(pow(exp(number),0.33333333333333333333)) /* :-) */
#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;
}
Vous pouvez utiliser un assemblage en ligne (dépendant de la plate-forme), par exemple pour x86: (fonctionne également pour les nombres négatifs)
#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;
}
Utilisez itoa pour convertir en chaîne de base 3. Supprimez le dernier trit et reconvertissez-le en 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
}
(note: voir Edit 2 ci-dessous pour une meilleure version!)
Ce n’est pas aussi compliqué que cela en a l'air, car vous avez dit "sans utiliser les opérateurs [..] +
[..] ". Voir ci-dessous, si vous souhaitez interdire l’utilisation simultanée du caractère +
.
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;
}
puis il suffit de dire div_by(100,3)
pour diviser 100
par 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)
}
+
, -
, *
, /
, %
.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;
}
Nous utilisons le premier argument de la fonction add
car nous ne pouvons pas désigner le type de pointeurs sans utiliser le caractère *
, sauf dans les listes de paramètres de fonction, où la syntaxe type[]
est identique à type* const
.
FWIW, vous pouvez facilement implémenter une fonction de multiplication en utilisant une astuce similaire pour utiliser l’astuce 0x55555556
proposée par AndreyT :
int mul(int const x, int const y) {
return sizeof(struct {
char const ignore[y];
}[x]);
}
C'est facilement possible sur le ordinateur Setun .
Pour diviser un entier par 3, décalage droit de 1 place .
Je ne sais pas s'il est strictement possible d'implémenter un compilateur C conforme sur une telle plate-forme. Nous devrons peut-être étirer un peu les règles, comme interpréter "au moins 8 bits" comme "capable de contenir au moins des entiers de -128 à +127".
Depuis Oracle, qu’en est-il d’une table de recherche de réponses pré-calculées? :-RÉ
Voici ma solution:
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);
}
Tout d'abord, notez que
1/3 = 1/4 + 1/16 + 1/64 + ...
Maintenant, le reste est simple!
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 + ...
Il ne reste plus qu’à additionner ces valeurs décalées un! Oops! Cependant, nous ne pouvons pas ajouter, alors nous devrons écrire une fonction add en utilisant des opérateurs binaires! Si vous connaissez les opérateurs au niveau des bits, ma solution devrait paraître assez simple ... mais juste au cas où vous ne l'êtes pas, je vais vous donner un exemple à la fin.
Une autre chose à noter est que je décale d’abord de 30 à gauche! Cela permet de s’assurer que les fractions ne sont pas arrondies.
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!
C'est simplement un ajout que vous avez appris en tant qu'enfant!
111
1011
+0110
-----
10001
Cette implémentation échec car nous ne pouvons pas ajouter tous les termes de l'équation:
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
Supposons le résultat de div_by_3(a)
= x, puis x <= floor(f(a, i)) < a / 3
. Quand a = 3k
, nous obtenons une mauvaise réponse.
Pour diviser un nombre de 32 bits par 3, on peut le multiplier par 0x55555556
, puis prendre les 32 bits supérieurs du résultat 64 bits.
Il ne reste plus maintenant qu'à implémenter la multiplication à l'aide d'opérations et de décalages de bits ...
Encore une autre solution. Cela devrait gérer toutes les entrées (y compris les entrées négatives) à l'exception de la valeur minimale d'un int, qui devrait être traitée comme une exception codée en dur. Cela consiste essentiellement en une division par soustraction, mais en utilisant uniquement des opérateurs de bits (décalages, xor et & complément). Pour une vitesse plus rapide, il soustrait 3 * (puissance décroissante de 2). En c #, il exécute environ 444 de ces appels DivideBy3 par milliseconde (2,2 secondes pour 1 000 000 de divisions), ce qui signifie qu’il n’est pas extrêmement lent, mais pas aussi rapide qu’un simple x/3. En comparaison, la solution Nice de Coodey est environ 5 fois plus rapide que celle-ci.
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'est c # parce que c'est ce que j'avais à portée de main, mais les différences avec c devraient être mineures.
C'est vraiment très facile.
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;
(J'ai bien sûr omis une partie du programme pour des raisons de brièveté.) Si le programmeur en a assez de taper tout cela, je suis sûr qu'il ou elle pourra écrire un programme séparé pour le générer. Je suis au courant d’un certain opérateur, /
, qui simplifierait énormément son travail.
L'utilisation de compteurs est une solution de base:
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
}
}
Il est également facile d'effectuer une fonction de module, vérifiez les commentaires.
Celui-ci est l'algorithme de division classique en base 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);
}
Ecrivez le programme en Pascal et utilisez l'opérateur DIV
.
Puisque la question est étiquetée c , vous pouvez probablement écrire une fonction en Pascal et l'appeler à partir de votre programme C; la méthode pour le faire est spécifique au système.
Mais voici un exemple qui fonctionne sur mon système Ubuntu avec le paquet Free Pascal _fp-compiler
_ installé. (Je le fais par pure obstination; je ne prétends pas que cela est utile.)
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;
}
_
Pour construire:
_fpc divide_by_3.pas && gcc divide_by_3.o main.c -o main
_
Exemple d'exécution:
_$ ./main
Enter a number: 100
100 / 3 = 33
_
int div3(int x)
{
int reminder = abs(x);
int result = 0;
while(reminder >= 3)
{
result++;
reminder--;
reminder--;
reminder--;
}
return result;
}
N'a pas vérifié si cette réponse est déjà publiée. Si le programme doit être étendu aux nombres flottants, les nombres peuvent être multipliés par 10 * nombre de précision nécessaire, puis le code suivant peut être appliqué à nouveau.
#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;
}
Utilisation de Mathématiques BC dans PHP :
<?php
$a = 12345;
$b = bcdiv($a, 3);
?>
MySQL (c'est une interview d'Oracle)
> SELECT 12345 DIV 3;
Pascal :
a:= 12345;
b:= a div 3;
x86-64 Langue d'assemblage:
mov r8, 3
xor rdx, rdx
mov rax, 12345
idiv r8
Cela devrait fonctionner pour tout diviseur, pas seulement trois. Actuellement, uniquement pour les non-signés, mais l’extension à signée ne devrait pas être aussi difficile.
#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;
}
Serait-il trompeur d'utiliser l'opérateur /
"dans les coulisses" en utilisant eval
et la concaténation de chaînes?
Par exemple, dans Javacript, vous pouvez faire
function div3 (n) {
var div = String.fromCharCode(47);
return eval([n, div, 3].join(""));
}
D'abord que je suis venu avec.
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
EDIT: Désolé, je n'ai pas remarqué le tag C
. Mais vous pouvez utiliser l’idée du formatage des chaînes, je suppose ...
Le script suivant génère un programme C qui résout le problème sans utiliser les opérateurs * / + - %
:
#!/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));
}
''')
Utiliser Calculateur de nombres de Hacker's Delight Magic
int divideByThree(int num)
{
return (fma(num, 1431655766, 0) >> 32);
}
Où fma est une fonction de bibliothèque standard définie dans l'en-tête math.h
.
Je pense que la bonne réponse est:
Pourquoi n'utiliserais-je pas un opérateur de base pour effectuer une opération de base?
Solution utilisant fonction de bibliothèque fma () , fonctionne pour tout nombre positif:
#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);
}
Comment sur cette approche (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;
}
Utilisez cblas , inclus dans la structure Accelerate d’OS X.
[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
Première:
x/3 = (x/4) / (1-1/4)
Puis trouvez comment résoudre 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))
avec 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)
}
Bien qu'il utilise +
, mais quelqu'un implémente déjà add by bitwise op.
Toutes les réponses ne sont probablement pas ce que l'intervieweur a aimé entendre:
Ma réponse:
"Je ne ferais jamais cela, qui me paierait pour des choses aussi stupides. Personne n'y aura d'avantage, ce n'est pas plus rapide, c'est seulement bête. Les concepteurs de Prozessor doivent le savoir, mais cela doit alors fonctionner pour tous les chiffres, pas seulement pour division par 3 "
D'accord, je pense que nous sommes tous d'accord pour dire que ce n'est pas un problème du monde réel. Donc, juste pour le plaisir, voici comment faire avec Ada et le multithreading:
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;
Très amusé, aucune réponse avec une division générique:
/* 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;
}
L'addition au niveau des bits a déjà été donnée dans l'une des réponses, donc sautez-la.
En règle générale, une solution à ce problème serait:
log(pow(exp(numerator),pow(denominator,-1)))
Pourquoi n'appliquons-nous pas simplement la définition étudiée au collège? Le résultat peut être inefficace mais clair, car la multiplication est simplement une soustraction récursive et la soustraction est une addition, puis l'addition peut être effectuée par une combinaison récursive xor/et de ports logiques.
#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;
}
Comme le dit quelqu'un ... faites d'abord ce travail. Notez que cet algorithme devrait fonctionner pour Q négatif ...
#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;
}
Si vous vous rappelez la méthode de division standard de l'école et que vous le faites en binaire, vous découvrirez que dans le cas de 3, vous ne divisez et ne soustrayez qu'un ensemble limité de valeurs (de 0 à 5 dans ce cas). Ceux-ci peuvent être traités avec une instruction switch pour se débarrasser des opérateurs arithmétiques.
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);
}
Où InputValue
est le nombre à diviser par 3
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
Cela fonctionnera:
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
Il suffit de remplacer "14" et "3" par vos chiffres.
3 en base 2 est 11.
Il suffit donc de faire une longue division (comme au collège) en base 2 par 11. C'est encore plus facile en base 2 qu'en base 10.
Pour chaque position de bit commençant par le plus significatif:
Décidez si le préfixe est inférieur à 11.
Si c'est la sortie 0.
S'il ne s'agit pas de la sortie 1, remplacez ensuite les bits de préfixe par la modification appropriée. Il n'y a que trois cas:
11xxx -> xxx (ie 3 - 3 = 0)
100xxx -> 1xxx (ie 4 - 3 = 1)
101xxx -> 10xxx (ie 5 - 3 = 2)
Tous les autres préfixes sont inaccessibles.
Répétez jusqu'à la position la plus basse et vous avez terminé.
J'utiliserais ce code pour diviser tous les nombres positifs non flottants. En gros, vous souhaitez aligner les bits du diviseur à gauche pour les faire correspondre aux bits de dividende. Pour chaque segment du dividende (taille du diviseur) que vous souhaitez vérifier pour vous assurer que le segment du dividende est supérieur au diviseur, vous souhaitez alors déplacer à gauche puis OR dans le premier registraire. Ce concept a été créé en 2004 (standford je crois), voici une version C qui utilise ce concept. Note: (je l'ai modifié un peu)
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)
}
Exemple d'utilisation:
int n = divide( 3, 6); //outputs 2
si on considère __div__
n'est pas orthographiquement /
def divBy3(n):
return n.__div__(3)
print divBy3(9), 'or', 9//3
Il semble que personne n'ait mentionné le critère de division pour 3 représenté en binaire - la somme des chiffres pairs devrait être égale à la somme des chiffres impairs (similaire au critère de 11 en décimal). Il existe des solutions en utilisant cette astuce sous Vérifiez si un nombre est divisible par .
Je suppose que c'est le doublon possible mentionné par le montage de Michael Burr.
#!/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