Solución:
Desarrollé una solución para la suma binaria en Javascript.
Mi objetivo inicial era solidificar mi comprensión de la lógica binaria replicando los mecanismos utilizados en los circuitos sumadores binarios digitales en Javascript (no se utilizan conversiones de base ni operadores bit a bit).
Puede encontrar una versión funcional de mi proyecto original en CodePen.
Está haciendo mucho más con el DOM de lo que probablemente necesita, pero cuando conecté sus números (con los ajustes que se mencionan a continuación), ¡me alegré de ver que funcionó!
Código de solución de trabajo << este proyecto se modificó de mi proyecto original y contiene solo el código necesario para generar la respuesta correcta.
Esta solución asume que a
y b
son cadenas de la misma longitud. Para usar esta solución, sus variables de entrada deben modificarse a:
var a = "000010100000100100110110010000010101111011011001101110111111111101000000101111001110001111100001101"
var b = "110101001011101110001111100110001010100001101011101010000011011011001011101111001100000011011110011"
(Acabo de completar los dígitos que faltan al principio de var a
con ceros.)
Como puede ver, recreé todos los componentes utilizados en una implementación física de un circuito sumador binario:
Mitad de víbora:
function halfAdder(a, b){
const sum = xor(a,b);
const carry = and(a,b);
return [sum, carry];
}
Sumador completo:
function fullAdder(a, b, carry){
halfAdd = halfAdder(a,b);
const sum = xor(carry, halfAdd[0]);
carry = and(carry, halfAdd[0]);
carry = or(carry, halfAdd[1]);
return [sum, carry];
}
Puertas lógicas:
function xor(a, b){return (a === b ? 0 : 1);}
function and(a, b){return a == 1 && b == 1 ? 1 : 0;}
function or(a, b){return (a || b);}
Función principal:
function addBinary(a, b){
let sum = '';
let carry = '';
for(var i = a.length-1;i>=0; i--){
if(i == a.length-1){
//half add the first pair
const halfAdd1 = halfAdder(a[i],b[i]);
sum = halfAdd1[0]+sum;
carry = halfAdd1[1];
}else{
//full add the rest
const fullAdd = fullAdder(a[i],b[i],carry);
sum = fullAdd[0]+sum;
carry = fullAdd[1];
}
}
return carry ? carry + sum : sum;
}
Por lo que entonces, addBinary(a,b)
produce la respuesta correcta!
var a = "000010100000100100110110010000010101111011011001101110111111111101000000101111001110001111100001101"
var b = "110101001011101110001111100110001010100001101011101010000011011011001011101111001100000011011110011"
var answer = "110111101100010011000101110110100000011101000101011001000011011000001100011110011010010011000000000";
console.log(addBinary(a, b) == answer); //true
¡Espero que algo de lo que he hecho aquí también pueda serle útil!
Aquí está mi opinión sobre esto:
La lógica es simple, como se enseña en la escuela primaria, comenzando desde el dígito más a la derecha: sumo el último dígito del primer número y el último dígito del segundo número, y guardo el acarreo para la siguiente ronda.
En cada ronda (dentro del while
) Recorto a la derecha ambos números, por ejemplo:
// number
1101 -> 110
// The math is simple: 1101/10|0 (divide by 10 and convert to integer)
Las entradas y salidas son Instrumentos de cuerda para superar las limitaciones máximas de enteros de JS, donde la longitud de una cadena puede ser mucho mayor.
Código completo:
function binaryAddition(a,b){
var result = "",
carry = 0;
while(a || b || carry){
let sum = +a.slice(-1) + +b.slice(-1) + carry; // get last digit from each number and sum
if( sum > 1 ){
result = sum%2 + result;
carry = 1;
}
else{
result = sum + result;
carry = 0;
}
// trim last digit (110 -> 11)
a = a.slice(0, -1)
b = b.slice(0, -1)
}
return result;
}
// Tests
[
["0","0"],
["1","1"],
["1","0"],
["0","1"],
["10","1"],
["11","1"],
["10","10"],
["111","111"],
["1010","11"]
].forEach(numbers =>
document.write(
numbers[0] + " + " +
numbers[1] + " = " +
binaryAddition(numbers[0], numbers[1]) +
" <mark> (" +
parseInt(numbers[0], 2) + " + " +
parseInt(numbers[1], 2) + " = " +
parseInt(binaryAddition(numbers[0], numbers[1]),2) +
")</mark><br>"
)
)
document.body.style="font:16px monospace";
Olvídese de la precisión de funcionamiento de Javascript, piense en cómo añadir un binario en matemáticas.
Por ejemplo, 11
+ 10
.
Primero, debemos comenzar de derecha a izquierda. Ahora tenemos
1 + 0 = 1
Después de eso, pasamos al siguiente.
1 + 1 = 10
Si usamos Javascript, cómo obtener el resultado.
Lo sabemos, Mod
puede obtener el número restante, Division
puede conseguir el transporte. En el sistema decimal, obtenemos 1 + 1 = 2
, como transferir 2
para 10
. Nosotros podemos usar
result % 2 // we can get single digit
result / 2 | 0 // we can get tens digit, `| 0` can remove decimal.
Ahora podemos concatizar las dos cadenas juntas.
BinaryNumber = result / 2 | 0 + result % 2 + '' // string concat
Entonces nuestro código final puede ser este:
/**
* @param {string} a
* @param {string} b
* @return {string}
*/
var addBinary = function(a, b) {
var i = a.length - 1;
var j = b.length - 1;
var carry = 0;
var result = "";
while(i >= 0 || j >= 0) {
var m = i < 0 ? 0 : a[i] | 0;
var n = j < 0 ? 0 : b[j] | 0;
carry += m + n; // sum of two digits
result = carry % 2 + result; // string concat
carry = carry / 2 | 0; // remove decimals, 1 / 2 = 0.5, only get 0
i--;
j--;
}
if(carry !== 0) {
result = carry + result;
}
return result;
};