Autor Tema: Convertir string binario a string decimal.

0 Usuarios y 1 Visitante están viendo este tema.

12 Agosto, 2025, 04:17 am
Leído 3661 veces

Tachikomaia

  • $$\Large \color{#5b61b3}\pi\,\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 1,297
  • País: uy
  • Karma: +0/-0
  • Sexo: Masculino
Lamento haber hecho preguntas en esta sección y no haberles dado mucho corte, estuve enfermo y además creo que son obstáculos que tendré pero necesito resolver este antes, por eso quiero concentrarme en este.

Tengo un string que es un número binario:
1111110111111011111101111110111111011111100000000

Uso esto para convertirlo en decimal:
Código: [Seleccionar]
        NroDelCaracter = 0;
ValorEnDecimal = 0;
do {
ValorEnDecimal = ValorEnDecimal+(Number(ValorEnBinario.charat(NroDelCaracter))*Math.round(Math.pow(2, ValorEnBinario.length-1-NroDelCaracter)));
NroDelCaracter++;
} while (NroDelCaracter<Cuadraditos);
ValorEnDecimal = Number(ValorEnDecimal);
Cuadraditos creo que es como la cantidad de caracteres. Cambié algunas palabras para que uds lo entiendan mejor, pero la cosa es, creo que funciona bien, es lo que he usado.

PERO si el string binario a convertir es demasiado grande, ese código me falla.

Necesito que el número decimal sea string, porque en mi lenguaje (Actionscript de Macromedia Flash 5) un número demasiado grande se aproxima a otro.

GPT me dijo:
Citar
Para no perder precisión en Flash 5 necesitas hacer aritmética “grande” con strings (sin usar Number para el valor completo). La idea: recorre el binario de izquierda a derecha y mantén el acumulado en decimal como un arreglo de dígitos; en cada bit haces “decimal = decimal*2 + bit”. Multiplicar por 2 y sumar 1 se hacen dígito a dígito.

Aquí tienes una función ActionScript (Flash 5) que convierte un string binario a su string decimal sin pérdida:

```actionscript
// Convierte un string binario (p.ej. "1101") a string decimal exacto (p.ej. "13")
// No usa Number para representar el valor completo, solo dígitos individuales.
function binToDecString(bin) {
  // Saltar ceros líderes
  var i = 0;
  var n = bin.length;
  while (i < n && bin.charAt(i) == "0") { i++; }
  if (i >= n) return "0";

  // digits almacena el número decimal en dígitos base 10, LSB primero (digits[0] es las unidades)
  var digits =
;

  for (; i < n; i++) {
    var c = bin.charAt(i);
    if (c != "0" && c != "1") {
      // Si hay caracteres no binarios, puedes elegir lanzar error o ignorar; aquí se ignoran.
      continue;
    }

    // decimal *= 2
    var carry = 0;
    var j;
    for (j = 0; j < digits.length; j++) {
      var x = digits[j] * 2 + carry; // x siempre pequeño, seguro
      digits[j] = x % 10;
      carry = Math.floor(x / 10);
    }
    while (carry > 0) {
      digits[digits.length] = carry % 10;
      carry = Math.floor(carry / 10);
    }

    // decimal += bit (0 o 1)
    if (c == "1") {
      var k = 0;
      var add = 1;
      while (add > 0) {
        if (k >= digits.length) digits[digits.length] = 0;
        var y = digits[k] + add;
        digits[k] = y % 10;
        add = Math.floor(y / 10);
        k++;
      }
    }
  }

  // Construir string (invertir los dígitos)
  var s = "";
  for (var t = digits.length - 1; t >= 0; t--) {
    s += digits[t];
  }
  return s;
}

// Ejemplos:
trace(binToDecString("0"));                // "0"
trace(binToDecString("1"));                // "1"
trace(binToDecString("10"));               // "2"
trace(binToDecString("11111111"));         // "255"
trace(binToDecString("10000000000000000"));// "131072"
```

Notas:
- Complejidad aproximada O(bits × dígitos_decimales). Para binarios muy largos funciona bien en Flash 5 si no son cientos de miles de bits.
- Si quieres validar estrictamente el input, en vez de “continue” cuando c != '0'/'1', lanza un error o retorna null.

Tengo que intentar entender ese código, pero ya había conseguido uno parecido y no pude. Le puedo ir preguntando a GPT lo que no entienda pero... si alguien pudiera hacer un código más comprensible y explicarlo con un ejemplo estaría bueno.

13 Agosto, 2025, 12:59 am
Respuesta #1

Richard R Richard

  • Ingeniero Industrial
  • $$\Large \color{#9c57a6}\pi\,\pi\,\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 4,054
  • País: ar
  • Karma: +2/-0
  • Sexo: Masculino
  • Dentro de la ciencia todo,fuera de la ciencia nada
 Aver si la IA te da lo que quieres...


Código: [Seleccionar]
// =========================================
// Normaliza número decimal en string
// Quita ceros a la izquierda y valida
function normDec(s) {
    s = String(s);
    s = stripLeadingPlus(s);
    if (s.indexOf("-") != -1) {
        trace("Error: No se admiten números negativos");
        return null;
    }
    if (!onlyDigits(s)) {
        trace("Error: El número contiene caracteres inválidos");
        return null;
    }
    s = stripLeadingZeros(s);
    if (s == "") {
        s = "0";
    }
    return s;
}


function stripLeadingPlus(s) {
    if (s.charAt(0) == "+") {
        return s.substr(1);
    }
    return s;
}


function stripLeadingZeros(s) {
    var i = 0;
    while (i < s.length && s.charAt(i) == "0") {
        i++;
    }
    return s.substr(i);
}


function onlyDigits(s) {
    var i;
    for (i = 0; i < s.length; i++) {
        var c = s.charCodeAt(i);
        if (c < 48 || c > 57) { // '0'=48, '9'=57
            return false;
        }
    }
    return true;
}


// =========================================
// Suma de strings decimales
function addStr(a, b) {
    a = normDec(a);
    b = normDec(b);
    if (a == null || b == null) return null;


    var i = a.length - 1;
    var j = b.length - 1;
    var carry = 0;
    var out = "";


    while (i >= 0 || j >= 0 || carry > 0) {
        var da = (i >= 0) ? (a.charCodeAt(i) - 48) : 0;
        var db = (j >= 0) ? (b.charCodeAt(j) - 48) : 0;
        var s = da + db + carry; // máximo 19
        out = String.fromCharCode((s % 10) + 48) + out;
        carry = Math.floor(s / 10); // 0 o 1
        i--;
        j--;
    }
    return out;
}


// =========================================
// Multiplica string decimal por dígito (0..9)
function mulStrDigit(a, d) {
    a = normDec(a);
    if (a == null) return null;
    if (d < 0 || d > 9) {
        trace("Error: multiplicador debe ser dígito");
        return null;
    }
    if (a == "0" || d == 0) return "0";
    if (d == 1) return a;


    var carry = 0;
    var out = "";
    var i;
    for (i = a.length - 1; i >= 0; i--) {
        var da = a.charCodeAt(i) - 48;
        var prod = da * d + carry; // máximo 89
        out = String.fromCharCode((prod % 10) + 48) + out;
        carry = Math.floor(prod / 10); // 0..8
    }
    if (carry > 0) {
        out = String.fromCharCode(carry + 48) + out;
    }
    return out;
}


// =========================================
// Multiplica dos strings decimales
function mulStr(a, b) {
    a = normDec(a);
    b = normDec(b);
    if (a == null || b == null) return null;
    if (a == "0" || b == "0") return "0";


    var res = "0";
    var zeros = "";
    var k;
    for (k = b.length - 1; k >= 0; k--) {
        var dk = b.charCodeAt(k) - 48;
        var parc = mulStrDigit(a, dk);
        if (parc != "0") {
            parc = parc + zeros;
            res = addStr(res, parc);
        }
        zeros += "0";
    }
    return res;
}


// =========================================
// Convierte binario string a decimal string
function binarioADecimalStr(binStr) {
    binStr = String(binStr);
    var s = stripLeadingZeros(binStr);
    if (s == "") return "0";
    var i;
    for (i = 0; i < s.length; i++) {
        if (s.charAt(i) != "0" && s.charAt(i) != "1") {
            trace("Error: binario inválido");
            return null;
        }
    }


    var acc = "0";
    for (i = 0; i < s.length; i++) {
        acc = mulStrDigit(acc, 2);
        if (s.charAt(i) == "1") {
            acc = addStr(acc, "1");
        }
    }
    return acc;
}


// =========================================
// Ejemplos:
trace(binarioADecimalStr("101101"));      // "45"
trace(binarioADecimalStr("11111111"));    // "255"
trace(binarioADecimalStr("1"));           // "1"
trace(binarioADecimalStr("0"));           // "0"


// Ejemplo con binario largo (64 bits):
trace(binarioADecimalStr("1111111111111111111111111111111111111111111111111111111111111111"));
// 18446744073709551615


Queda en tí entenderlo y aplicarlo ,  lo que hice fue pedirlo en Python y que lo convierta a tu lenguaje, así que con esa sintaxis no lo entiendo, fui especifico que no maneje ninguna variable con enteros de mas de 16 cifras y de echo creo solo usa dos...


Espero te sirva.
Saludos  \(\mathbb {R}^3\)

19 Agosto, 2025, 02:05 am
Respuesta #2

Tachikomaia

  • $$\Large \color{#5b61b3}\pi\,\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 1,297
  • País: uy
  • Karma: +0/-0
  • Sexo: Masculino
Esto no sé qué es:
 s = stripLeadingPlus(s);
    if (s.indexOf("-") != -1) {
capaz que te lo hizo en Adobe Flash 5, yo uso el de Macromedia que es más antiguo.

El código ya me lo dió, lo puse al inicio. Ahora voy a hablar con él porque ya lo intenté entender y no pude. Luego actualizo.

19 Agosto, 2025, 02:47 am
Respuesta #3

Richard R Richard

  • Ingeniero Industrial
  • $$\Large \color{#9c57a6}\pi\,\pi\,\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 4,054
  • País: ar
  • Karma: +2/-0
  • Sexo: Masculino
  • Dentro de la ciencia todo,fuera de la ciencia nada
Esto no sé qué es:
 s = stripLeadingPlus(s);
    if (s.indexOf("-") != -1) {
capaz que te lo hizo en Adobe Flash 5, yo uso el de Macromedia que es más antiguo.

El código ya me lo dió, lo puse al inicio. Ahora voy a hablar con él porque ya lo intenté entender y no pude. Luego actualizo.
Yo le pedí que lo pase a Action Script 5 ,  pidele que cambie esa sentencia para tu código.

Saludos  \(\mathbb {R}^3\)

19 Agosto, 2025, 03:08 am
Respuesta #4

Tachikomaia

  • $$\Large \color{#5b61b3}\pi\,\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 1,297
  • País: uy
  • Karma: +0/-0
  • Sexo: Masculino
Bueno hablé hasta no tener puntos. Probablemente no tenga mucho sentido copiar la conversación pero acá va un resumen:
qué significa Saltar ceros líderes
Citar
Ignorar los 0s que están al inicio del binario

explica esto
  while (i < n && bin.charAt(i) == "0") { i++; }
  if (i >= n) return "0";

no sé si el while ha terminado, etc. Lo veo así:
while (i < n && bin.charAt(i) == "0") {
   i++;
}
if (i >= n) return "0";
y sigue ¿es así?

Citar
Sí

cambié los i por NroDeCaracteraMirar:
(código)
¿tengo que cambiar los siguientes i o son independientes? Este:
  for (; i < n; i++) {

Citar
Representan lo mismo, debes cambiarlos también

la variable n es el largo del binario, siempre?

Citar
sí

var para qué es, qué diferencia hay entre definir una variable con var y sin var

Citar
En ActionScript (especialmente en Flash 5/ActionScript 1), var sirve para declarar variables con alcance local a la función o al clip donde se declaran. Si no usas var, la variable se crea de forma implícita en un ámbito más global, lo que puede provocar efectos secundarios.

Diferencias clave:

- Con var:
  - Crea una variable local al ámbito actual (normalmente la función).
  - Solo existe mientras se ejecuta esa función.
  - No “ensucia” el timeline/objeto global.
  - Mejor rendimiento y menos riesgos de colisiones de nombres.

- Sin var:
  - Crea o sobrescribe una propiedad en el objeto actual (this) o en el nivel global (_root en muchos casos).
  - Persiste después de terminar la función.
  - Puede pisar variables/propiedades existentes y causar bugs difíciles de rastrear.
  - En proyectos grandes, suele generar “fugas” de estado.

Buenas prácticas en Flash 5:
- Declara siempre tus variables con var dentro de funciones.
- Evita depender de variables implícitas globales.
- Usa nombres claros (como hiciste con LargoDelBinario) y mantén la consistencia.

No sabía o me había olvidado, a veces creaba variables y luego las eliminaba, de esta forma se eliminan solas.

cómo este if no tiene el { ?
  if (NroDeCaracteraMirar >= LargoDelBinario) return "0";
normalmente se pone
si (condición) {
   efecto

Citar
En muchos lenguajes (incluido ActionScript/javascript), si el if controla una sola sentencia, puedes omitir las llaves. Estas dos formas son equivalentes:

- Forma compacta en una sola línea:
  if (condicion) return "0";

- Forma “normal” con llaves:
  if (condicion) {
    return "0";
  }

- Forma sin llaves pero en varias líneas (no recomendada por claridad):
  if (condicion)
    return "0";

Recomendación:
- Usa llaves siempre, incluso para una única sentencia, por legibilidad y para evitar errores al agregar otra línea después. Por ejemplo, este cambio accidental introduce un bug si no hay llaves:

  if (condicion)
    hacerAlgo();
    hacerOtraCosa(); // se ejecutará siempre, no está dentro del if

Con llaves, eso no pasa.

¿es posible que NroDeCaracteraMirar quede mayor que LargoDelBinario?
  // Ignorar ceros al inicio del binario:
  var NroDeCaracteraMirar = 0;
  var LargoDelBinario = bin.length;
  // Para eso mira caracteres desde la izquierda hasta que no haya caracteres o hasta que no sea 0:
  while (NroDeCaracteraMirar < LargoDelBinario && bin.charAt(NroDeCaracteraMirar) == "0") {
    NroDeCaracteraMirar++;
  }
  if (NroDeCaracteraMirar >= LargoDelBinario) {
   return "0";
  }

el incremento de NroDeCaracteraMirar ocurre sólo si es menor que LargoDelBinario, por lo que en cierto punto quedará igual y luego ya no aumentará, por lo tanto NroDeCaracteraMirar nunca será mayor que LargoDelBinario ¿correcto?

Citar
Sí.

Código más claro (aún falta aclararlo más):
Código: [Seleccionar]
// Convierte un string binario (p.ej. "1101") a string decimal exacto (p.ej. "13")
// No usa Number para representar el valor completo, solo dígitos individuales.
function binToDecString(bin) {
  // Ignorar ceros al inicio del binario:
  var NroDeCaracteraMirar = 0;
  var LargoDelBinario = bin.length;
  // Para eso mira caracteres desde la izquierda hasta que no haya caracteres o hasta que no sea 0:
  while (NroDeCaracteraMirar < LargoDelBinario && bin.charAt(NroDeCaracteraMirar) == "0") {
    NroDeCaracteraMirar++;
  }
  // Si miró todos los caracteres:
  if (NroDeCaracteraMirar == LargoDelBinario) {
return "0";
  }
 
  // digits almacena el número decimal en dígitos base 10, LSB primero (digits[0] es las unidades)
  var digits = [0];

  // Recorremos desde el primer '1' encontrado
  for (; NroDeCaracteraMirar < LargoDelBinario; NroDeCaracteraMirar++) {
    var c = bin.charAt(NroDeCaracteraMirar);
    if (c != "0" && c != "1") {
      continue; // o maneja error si prefieres
    }

    // decimal *= 2
    var carry = 0;
    var j;
    for (j = 0; j < digits.length; j++) {
      var x = digits[j] * 2 + carry;
      digits[j] = x % 10;
      carry = Math.floor(x / 10);
    }
    while (carry > 0) {
      digits[digits.length] = carry % 10;
      carry = Math.floor(carry / 10);
    }

    // decimal += bit
    if (c == "1") {
      var k = 0;
      var add = 1;
      while (add > 0) {
        if (k >= digits.length) digits[digits.length] = 0;
        var y = digits[k] + add;
        digits[k] = y % 10;
        add = Math.floor(y / 10);
        k++;
      }
    }
  }

  // Construir string (invertir los dígitos)
  var s = "";
  for (var t = digits.length - 1; t >= 0; t--) {
    s += digits[t];
  }
  return s;
}