Last active
August 18, 2021 18:22
-
-
Save bencz/7dbdf3cfe270ac2f2b8f to your computer and use it in GitHub Desktop.
Tipo pró!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#if _MSC_VER | |
#define ASMDEF __asm | |
#elif __ORANGEC__ || __DMC__ | |
#define ASMDEF asm | |
#endif | |
int xor(int a, int b) | |
{ | |
// a forma mais simples de se calcular o XOR | |
// a+b-2*and(a,b) | |
int c = 0; | |
for (int x = 0; x <= 31; ++x) | |
{ | |
c += c; | |
if (a < 0) | |
{ | |
if (b >= 0) | |
{ | |
c += 1; | |
} | |
} | |
else if (b < 0) | |
{ | |
c += 1; | |
} | |
a += a; | |
b += b; | |
} | |
return c; | |
} | |
// & | |
int and(int a, int b) | |
{ | |
int c = 0; | |
for (int x = 0; x <= 31; ++x) | |
{ | |
c += c; | |
if (a < 0) | |
{ | |
if (b < 0) | |
{ | |
c += 1; | |
} | |
} | |
a += a; | |
b += b; | |
} | |
return c; | |
} | |
// | ( or ) | |
int or(int a, int b) | |
{ | |
int c = 0; | |
for (int x = 0; x <= 31; ++x) | |
{ | |
c += c; | |
if (a < 0) | |
{ | |
c += 1; | |
} | |
else if (b < 0) | |
{ | |
c += 1; | |
} | |
a += a; | |
b += b; | |
} | |
return c; | |
} | |
int powtab[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, -32768 }; | |
int shiftRight(int a, int shift) | |
{ | |
if (shift >= 15) | |
{ | |
if (a < 0) | |
{ | |
a = -1; | |
} | |
else | |
{ | |
a = 0; | |
} | |
} | |
else if (shift > 0) | |
{ | |
if (a < 0) | |
{ | |
a += -32768; | |
a /= powtab[shift]; | |
a -= powtab[15 - shift]; | |
} | |
else | |
{ | |
a /= powtab[shift]; | |
} | |
} | |
return a; | |
} | |
unsigned int uShiftRight(int a, int shift) | |
{ | |
if (shift > 15) | |
{ | |
a = 0; | |
} | |
else if (shift > 0) | |
{ | |
if (a < 0) | |
{ | |
a += -32768; | |
a /= powtab[shift]; | |
a += powtab[15 - shift]; | |
} | |
else | |
{ | |
a /= powtab[shift]; | |
} | |
} | |
return a; | |
} | |
// signed | |
int shiftLeft(int a, int shift) | |
{ | |
if (shift > 15) | |
{ | |
a = 0; | |
} | |
else | |
{ | |
a *= powtab[shift]; | |
} | |
return a; | |
} | |
int somar(int x, int y) | |
{ | |
int carry = 0; | |
#if (__ORANGEC__ || __DMC__ || _MSC_VER) && __USE_ASM_FUNCTIONS__ | |
ASMDEF | |
{ | |
FazSoma: | |
cmp[y], 0 | |
je Exit | |
mov eax, [x] | |
and eax, [y] | |
mov[carry], eax | |
mov ecx, [x] | |
xor ecx, [y] | |
mov[x], ecx | |
mov edx, [carry] | |
shl edx, 1 | |
mov[y], edx | |
jmp FazSoma | |
Exit: | |
mov eax, [x] | |
mov[x], eax | |
} | |
#else | |
while (y != 0) | |
{ | |
carry = and(x, y); | |
x = xor(x,y); | |
y = shiftLeft(carry, 1); | |
} | |
#endif | |
return x; | |
} | |
void incrementar(int *variable, int qnt) | |
{ | |
#if (__ORANGEC__ || __DMC__ || _MSC_VER) && __USE_ASM_FUNCTIONS__ | |
ASMDEF | |
{ | |
mov eax, [qnt] | |
push eax | |
mov ecx, [variable] | |
mov edx, [ecx] | |
push edx | |
call somar | |
add esp, 8 // alinha a pilha.. | |
mov ecx, [variable] | |
mov[ecx], eax | |
} | |
#else | |
*variable = somar(*variable, qnt); | |
#endif | |
} | |
int negar(int x) | |
{ | |
int retVal; | |
#if (__ORANGEC__ || __DMC__ || _MSC_VER) && __USE_ASM_FUNCTIONS__ | |
ASMDEF | |
{ | |
push 1 | |
mov eax, [x] | |
not eax | |
push eax | |
call somar | |
add esp, 8 | |
mov[retVal], eax | |
} | |
#else | |
retVal = somar(~x, 1); | |
#endif | |
return retVal; | |
} | |
int subtrair(int x, int y) | |
{ | |
int retSub = 0; | |
#if (__ORANGEC__ || __DMC__ || _MSC_VER) && __USE_ASM_FUNCTIONS__ | |
ASMDEF | |
{ | |
mov eax, [y] | |
push eax | |
call negar | |
add esp, 4 | |
push eax | |
mov ecx, [x] | |
push ecx | |
call somar | |
add esp, 8 | |
mov[retSub], eax | |
} | |
#else | |
retSub = somar(x, negar(y)); | |
#endif | |
return retSub; | |
} | |
int dividir_por_dois(int numero) | |
{ | |
int resultado; | |
#if (__ORANGEC__ || __DMC__ || _MSC_VER) && __USE_ASM_FUNCTIONS__ | |
ASMDEF | |
{ | |
mov eax, [numero] | |
sar eax, 1 | |
mov[resultado], eax | |
} | |
#else | |
resultado = shiftRight(numero,1); | |
#endif | |
return resultado; | |
} | |
int multiplicar_por_dois(int numero) | |
{ | |
int resultado; | |
#if (__ORANGEC__ || __DMC__ || _MSC_VER) && __USE_ASM_FUNCTIONS__ | |
ASMDEF | |
{ | |
mov eax, [numero] | |
shl eax, 1 | |
mov[resultado], eax | |
} | |
#else | |
resultado = shiftLeft(numero, 1); | |
#endif | |
return resultado; | |
} | |
int ehPar(int x) | |
{ | |
int resultado; | |
#if (__ORANGEC__ || __DMC__ || _MSC_VER) && __USE_ASM_FUNCTIONS__ | |
ASMDEF | |
{ | |
mov eax, [x] | |
not eax | |
and eax, 1 | |
mov[resultado], eax | |
} | |
#else | |
resultado = !(x & 1); | |
#endif | |
return resultado; | |
} | |
int ehImpar(int x) | |
{ | |
int resultado; | |
#if (__ORANGEC__ || __DMC__ || _MSC_VER) && __USE_ASM_FUNCTIONS__ | |
ASMDEF | |
{ | |
mov eax, [x] | |
and eax, 1 | |
mov[resultado], eax | |
} | |
#else | |
resultado = !(ehPar(x)); | |
#endif | |
return resultado; | |
} | |
int multiplicar(int x, int y) | |
{ | |
int produto = 0; | |
#if (__ORANGEC__ || __DMC__ || _MSC_VER) && __USE_ASM_FUNCTIONS__ | |
ASMDEF | |
{ | |
cmp[x], 0 | |
jge MulLoop1 | |
cmp[y], 0 | |
jge MulLoop1 | |
mov eax, [y] | |
push eax | |
call negar | |
add esp, 4 | |
push eax | |
mov ecx, [x] | |
push ecx | |
push ecx | |
call negar | |
add esp, 4 | |
push eax | |
call multiplicar | |
add esp, 8 | |
jmp MulLoop6 | |
MulLoop1: | |
cmp[x], 0 | |
jl MulLoop2 | |
cmp[y], 0 | |
jge MulLoop2 | |
mov edx, [x] | |
push edx | |
mov eax, [y] | |
push eax | |
call multiplicar | |
add esp, 8 | |
jmp MulLoop6 | |
MulLoop2: | |
cmp[y], 0 | |
jle MulLoop5 | |
mov ecx, [y] | |
push ecx | |
call ehPar | |
add esp, 4 | |
test eax, eax | |
je MulLoop3 | |
mov edx, [x] | |
push edx | |
call multiplicar_por_dois | |
add esp, 4 | |
mov[x], eax | |
mov eax, [y] | |
push eax | |
call dividir_por_dois | |
add esp, 4 | |
mov[y], eax | |
jmp MulLoop4 | |
MulLoop3: | |
mov ecx, [x] | |
push ecx | |
mov edx, [produto] | |
push edx | |
call somar | |
add esp, 8 | |
mov[produto], eax | |
push - 1 | |
mov eax, [y] | |
push eax | |
call somar | |
add esp, 8 | |
mov[y], eax | |
MulLoop4: | |
jmp MulLoop2 | |
MulLoop5: | |
mov eax, [produto] | |
MulLoop6: | |
mov[produto], eax | |
} | |
#else | |
if (x < 0 && y < 0) | |
return multiplicar(negar(x), negar(y)); | |
if (x >= 0 && y < 0) | |
return multiplicar(y, x); | |
while (y > 0) | |
{ | |
if (ehPar(y)) | |
{ | |
x = multiplicar_por_dois(x); | |
y = dividir_por_dois(y); | |
} | |
else | |
{ | |
produto = somar(produto, x); | |
y = somar(y, -1); | |
} | |
} | |
#endif | |
return produto; | |
} | |
int dividir(int dividendo, int divisor) | |
{ | |
int temp = 1; | |
int quociente = 0; | |
#if (__ORANGEC__ || __DMC__ || _MSC_VER) && __USE_ASM_FUNCTIONS__ | |
ASMDEF | |
{ | |
Dividir1: | |
mov eax, [divisor] | |
cmp eax, [dividendo] | |
jg Dividir2 | |
mov ecx, [divisor] | |
shl ecx, 1 | |
mov[divisor], ecx | |
mov edx, [temp] | |
shl edx, 1 | |
mov[temp], edx | |
jmp Dividir1 | |
Dividir2: | |
cmp[temp], 1 | |
jle Exit | |
mov eax, [divisor] | |
sar eax, 1 | |
mov[divisor], eax | |
mov ecx, [temp] | |
sar ecx, 1 | |
mov[temp], ecx | |
mov edx, [dividendo] | |
cmp edx, [divisor] | |
jl Dividir3 | |
mov eax, [divisor] | |
push eax | |
mov ecx, [dividendo] | |
push ecx | |
call subtrair | |
add esp, 8 | |
mov[dividendo], eax | |
mov edx, [temp] | |
push edx | |
mov eax, [quociente] | |
push eax | |
call somar | |
add esp, 8 | |
mov[quociente], eax | |
Dividir3: | |
jmp Dividir2 | |
Exit: | |
} | |
#else | |
while (divisor <= dividendo) | |
{ | |
divisor = shiftLeft(divisor, 1); | |
temp = shiftLeft(temp,1); | |
} | |
while (temp > 1) | |
{ | |
divisor = shiftRight(divisor, 1); | |
temp = shiftRight(temp, 1); | |
if (dividendo >= divisor) | |
{ | |
dividendo = subtrair(dividendo, divisor); | |
quociente = somar(quociente, temp); | |
} | |
} | |
#endif | |
return quociente; | |
} | |
int main() | |
{ | |
int x = 90; | |
int y = 18; | |
printf("XOR LOGICO: %d^%d=%d\n", x, y, x^y); | |
printf("XOR MATEMA: %d^%d=%d\n", x, y, xor(x, y)); | |
printf("RSHIFT LOGICO: %d\n", x >> 1); | |
printf("RSHIFT MATEMA: %d\n", shiftRight(x, 1)); | |
printf("URSHIFT MATEM: %d\n", uShiftRight(x, 1)); | |
printf("LSHIFT LOGICO: %d\n", x << 1); | |
printf("LSHIFT MATEMA: %d\n", shiftLeft(x, 1)); | |
printf("OR LOGICO: %d\n", x | y); | |
printf("OR MATEMA: %d\n", or(x, y)); | |
printf("AND LOGICO: %d\n", x & y); | |
printf("AND MATEMA: %d\n", and(x, y)); | |
int i = 0; | |
int incremento = 20; | |
printf("Somar............: 20+20=%d\n", somar(20, 20)); | |
printf("Subtrair.........: 30-10=%d\n", subtrair(30, 10)); | |
printf("Negar............: ~10=%d\n", negar(10)); | |
printf("Multiplicar......: 70*27=%d\n", multiplicar(70, 27)); | |
printf("Dividir(inteiros): 36/06=%d\n", dividir(36, 6)); | |
printf("Multiplicar por 2: 70*02=%d\n", multiplicar_por_dois(70)); | |
printf("Dividir por 2....: 40/02=%d\n\n", dividir_por_dois(40)); | |
incrementar(&incremento, 1); | |
printf("Incrementar: 20+01=%d\n", incremento); | |
printf("7 eh impar.: %s\n", ehImpar(7) ? "true" : "false"); | |
printf("2 eh impar.: %s\n", ehImpar(2) ? "true" : "false"); | |
printf("8 eh par...: %s\n", ehPar(8) ? "true" : "false"); | |
printf("7 eh par...: %s\n", ehPar(7) ? "true" : "false"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment