Joelg4dea

Java | base X --> base Y

Dec 6th, 2021 (edited)
567
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.     Java with Maven - Java application
  3.  
  4.     Product Version: Apache NetBeans IDE 12.4
  5.     Java: 16.0.2; Java HotSpot(TM) 64-Bit Server VM 16.0.2+7-67
  6.     Runtime: Java(TM) SE Runtime Environment 16.0.2+7-67
  7.  
  8.     Nombre de proyecto: jeolPr
  9.     Nombre de clase principal: bx_a_by
  10.  
  11.  
  12.     Base máxima: 36.
  13.     Se aceptan números flotantes.
  14.     No se puede ingresar negativos.
  15.  
  16.     Entero máximo: ilimitado.
  17.     Fraccionario máximo: 128 dígitos por defecto.
  18.     Se puede cambiar a gusto la cantidad máxima de números flotantes (de la salida) con la variable
  19.     maxFlotantes (valor 128 por defecto) [línea 56]. Así como también la cantidad máxima de dígitos
  20.     flotantes que se procesará, con ELIMITADO (1350 por defecto) [línea 57]. Recomiendo cambiar
  21.     ambos valores para que no surjan problemas al convertir fraccionarios muuuuuuuuuuy largos.
  22.  
  23.  
  24.     Aumentar los valores máximos puede ralentizar el proceso de conversión.
  25.  
  26.  
  27.     Actualización: aumentada la legibilidad del código en algunas secciones, mejorado el proceso
  28.     de conversión con números increíblemente grandes y optimizado a fin de evitar la redundancia.
  29.     Ahora los números convertidos no necesitarán redondeo.
  30.  
  31.  
  32.     El código fue probado con 16.000 dígitos enteros y 13.000 fraccionarios. No da problemas.
  33.     Pruebas:    https://pastebin.com/F13pknpP
  34.  
  35.  
  36.     EL ALGORITMO NO CUENTA CON COMENTARIOS.
  37. */
  38. package com.mycompany.jeolPr;
  39.  
  40. import java.util.Scanner;                       //      Para pedir datos.
  41. import java.math.BigDecimal;                //      Para obtener la mayor precision en la conversión.
  42. import java.math.MathContext;             //      Para definir el contexto en los cálculos de flotantes.
  43. import java.math.RoundingMode;         //      Para definir el modo de redondeo.
  44.  
  45. class Numerowo {
  46.  
  47.     static Scanner input = new Scanner(System.in);
  48.     static char[] Caracteres0Z = new char[36];
  49.     static char[] Caracteres09 = new char[10];
  50.     static boolean Fraccional;
  51.     static byte[] Numero, NumeroFraccional = {0, 0};
  52.     static BigDecimal numeroDecimal = new BigDecimal("0.0"), numeroFraccional = new BigDecimal("0.0"), Base, BaseFinal;
  53.     static BigDecimal comparador = new BigDecimal("0.99999");
  54.     static String numeroFinal = "";
  55.     static String flotador = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001";
  56.     static short maxFlotantes = 128;                           //      Cantidad de números flotantes máximos en la salida.
  57.     static MathContext ELIMITADO = new MathContext(1350, RoundingMode.DOWN);      //      Precisión en los cálculos de flotantes.
  58.     static boolean Agilizar = false;
  59.     /*      Esta variable controla que no se realice el cálculo DE base 10 A base 10 cuando
  60.     se plantea la conversión de un número decimal a base Y, o de un número de base X a
  61.     decimal. La desventaja de colocar la variable en "false" es que algunas conversiones de
  62.     base X a decimal, o viceversa, tardarán muchísimo más en realizarse. Tenerla en true
  63.     causa que el número final ignore maxFlotantes solo si la base destino es 10.
  64.      */
  65. }
  66.  
  67. public class bx_a_by {
  68.  
  69.     public static void llenarCaracteres() {
  70.         for (char a = 0; a < 10; a++) {
  71.             Numerowo.Caracteres09[a] = (char) ('0' + a);
  72.         }
  73.  
  74.         for (char a = 0; a < 36; a++) {
  75.             if (a < 10) {
  76.                 Numerowo.Caracteres0Z[a] = (char) ('0' + a);
  77.             } else {
  78.                 Numerowo.Caracteres0Z[a] = (char) ('7' + a);    // '7' + 10 = 'A'
  79.             }
  80.         }
  81.     }
  82.  
  83.     public static void pedirDatums() {
  84.         String Base, BaseFinal, Numero;
  85.  
  86.         System.out.println("Base mínima: 2\tBase máxima: 36");
  87.  
  88.         do {
  89.             do {
  90.                 System.out.println("Ingrese la base de su número:");
  91.                 Base = Numerowo.input.nextLine();
  92.             } while (chequearBase(Base));
  93.  
  94.             Numerowo.Base = BigDecimal.valueOf(Double.parseDouble(Base));
  95.             System.out.println();
  96.  
  97.             do {
  98.                 System.out.println("Ingrese la base final:");
  99.                 BaseFinal = Numerowo.input.nextLine();
  100.             } while (chequearBase(BaseFinal));
  101.  
  102.             Numerowo.BaseFinal = BigDecimal.valueOf(Double.parseDouble(BaseFinal));
  103.             System.out.println();
  104.         } while (chequearBasesiñas());
  105.  
  106.         System.out.println("Se acepta número fraccional (con punto).");
  107.  
  108.         do {
  109.             System.out.println("Ingrese un número:");
  110.             Numero = Numerowo.input.nextLine().toUpperCase();
  111.         } while (chequearNumero(Numero));
  112.     }
  113.  
  114.     public static boolean chequearBase(String text) {
  115.         long caracteresVálidos = 0;
  116.  
  117.         for (int i = 0; i < text.length(); i++) {
  118.             for (char num : Numerowo.Caracteres09) {
  119.                 if (num == text.charAt(i)) {
  120.                     caracteresVálidos++;
  121.                     break;
  122.                 }
  123.             }
  124.         }
  125.  
  126.         if (caracteresVálidos == text.length() && !"".equals(text)) {
  127.             if (Double.parseDouble(text) >= 2 && Double.parseDouble(text) <= 36) {
  128.                 return false;
  129.             }
  130.         }
  131.         return true;
  132.     }
  133.  
  134.     public static boolean chequearBasesiñas() {
  135.         if (Numerowo.BaseFinal.compareTo(Numerowo.Base) == 0) {
  136.             System.out.println("La base origen y base final son iguales '~' \n\n");
  137.             return true;
  138.         }
  139.  
  140.         return false;
  141.     }
  142.  
  143.     public static boolean chequearNumero(String text) {
  144.         long caracteresVálidos = 0;
  145.  
  146.         Numerowo.Fraccional = false;
  147.  
  148.         for (int i = 0; i < text.length(); i++) {
  149.  
  150.             if (Numerowo.Fraccional == false && text.charAt(i) == '.') {
  151.                 Numerowo.Fraccional = true;
  152.                 caracteresVálidos++;
  153.                 continue;
  154.             }
  155.  
  156.             for (char num : Numerowo.Caracteres0Z) {
  157.                 if (num == text.charAt(i)) {
  158.                     caracteresVálidos++;
  159.                     break;
  160.                 }
  161.             }
  162.         }
  163.  
  164.         if (caracteresVálidos == text.length() && !"".equals(text)) {
  165.             return obtenerNumero(text);
  166.         }
  167.  
  168.         return true;
  169.     }
  170.  
  171.     public static boolean obtenerNumero(String text) {
  172.         if (Numerowo.Fraccional) {
  173.             text += Numerowo.flotador;
  174.            
  175.             int indiceP = text.indexOf('.');
  176.             int indiceF = text.length() - indiceP - 1;
  177.  
  178.             Numerowo.NumeroFraccional = new byte[indiceF];
  179.             Numerowo.Numero = new byte[indiceP];
  180.  
  181.             for (int i = 0, x = indiceP + 1; i < indiceF; i++, x++) {
  182.                 for (byte y = 0; y < Numerowo.Base.doubleValue(); y++) {
  183.                     if (Numerowo.Caracteres0Z[y] == text.charAt(x)) {
  184.                         Numerowo.NumeroFraccional[i] = y;
  185.                         break;
  186.                     } else {
  187.                         Numerowo.NumeroFraccional[i] = -1;
  188.                     }
  189.                 }
  190.             }
  191.  
  192.             for (int i = 0; i < indiceP; i++) {
  193.                 for (byte y = 0; y < Numerowo.Base.doubleValue(); y++) {
  194.                     if (Numerowo.Caracteres0Z[y] == text.charAt(i)) {
  195.                         Numerowo.Numero[i] = y;
  196.                         break;
  197.                     } else {
  198.                         Numerowo.Numero[i] = -1;
  199.                     }
  200.                 }
  201.             }
  202.         } else {
  203.             Numerowo.Numero = new byte[text.length()];
  204.  
  205.             for (int i = 0; i < text.length(); i++) {
  206.                 for (byte y = 0; y < Numerowo.Base.doubleValue(); y++) {
  207.                     if (Numerowo.Caracteres0Z[y] == text.charAt(i)) {
  208.                         Numerowo.Numero[i] = y;
  209.                         break;
  210.                     } else {
  211.                         Numerowo.Numero[i] = -1;
  212.                     }
  213.                 }
  214.             }
  215.         }
  216.  
  217.         for (byte Entierro : Numerowo.Numero) {
  218.             if (Entierro == -1) {
  219.                 System.out.println("El número no concuerda con la base especificada.");
  220.                 return true;
  221.             }
  222.         }
  223.  
  224.         for (byte Frajelo : Numerowo.NumeroFraccional) {
  225.             if (Frajelo == -1) {
  226.                 System.out.println("La parte fraccional no concuerda con la base especificada.");
  227.                 return true;
  228.             }
  229.         }
  230.  
  231.         return false;
  232.     }
  233.  
  234.     public static void obtenerDecimal() {
  235.  
  236.         if (Numerowo.Agilizar && Numerowo.Base.compareTo(BigDecimal.TEN) == 0) {
  237.  
  238.             String GG = "";
  239.  
  240.             for (byte a : Numerowo.Numero) {
  241.                 GG += Integer.toString(a);
  242.             }
  243.  
  244.             Numerowo.numeroDecimal = new BigDecimal(GG);
  245.  
  246.             if (Numerowo.Fraccional) {
  247.  
  248.                 GG = "0.";
  249.  
  250.                 for (byte a : Numerowo.NumeroFraccional) {
  251.                     GG += Integer.toString(a);
  252.                 }
  253.  
  254.                 Numerowo.numeroFraccional = new BigDecimal(GG);
  255.             }
  256.         } else {
  257.  
  258.             BigDecimal G,
  259.                     base = Numerowo.Base,
  260.                     N = Numerowo.numeroDecimal,
  261.                     FR = Numerowo.numeroFraccional;
  262.  
  263.             for (int a = 0, b = Numerowo.Numero.length - 1; a < Numerowo.Numero.length; a++, b--) {
  264.  
  265.                 G = new BigDecimal(Numerowo.Numero[b]);
  266.  
  267.                 N = N.add(base.pow(a).multiply(G));
  268.             }
  269.  
  270.             Numerowo.numeroDecimal = N;
  271.  
  272.             if (Numerowo.Fraccional) {
  273.  
  274.                 int a = -1;
  275.  
  276.                 MathContext Ellie = Numerowo.ELIMITADO;
  277.  
  278.                 for (byte A : Numerowo.NumeroFraccional) {
  279.  
  280.                     FR = FR.add((base.pow(a, Ellie)).multiply(BigDecimal.valueOf(A)));
  281.  
  282.                     a--;
  283.                 }
  284.  
  285.                 Numerowo.numeroFraccional = FR;
  286.             }
  287.         }
  288.     }
  289.  
  290.     public static void obtenerConvertido() {
  291.  
  292.         if (Numerowo.Agilizar && Numerowo.BaseFinal.compareTo(BigDecimal.TEN) == 0) {
  293.  
  294.             Numerowo.numeroFinal = (new BigDecimal(Numerowo.numeroDecimal.toBigInteger()).add(Numerowo.numeroFraccional)).toPlainString();
  295.  
  296.         } else {
  297.  
  298.             BigDecimal N = new BigDecimal(Numerowo.numeroDecimal.toBigInteger()),
  299.                     base = new BigDecimal(Numerowo.BaseFinal.toPlainString()),
  300.                     F = new BigDecimal(Numerowo.numeroFraccional.toPlainString());
  301.  
  302.             do {
  303.                 Numerowo.numeroFinal += Numerowo.Caracteres0Z[N.remainder(base).byteValue()];
  304.  
  305.                 N = N.divideToIntegralValue(base);
  306.  
  307.             } while (N.divide(base, MathContext.DECIMAL128).compareTo(Numerowo.comparador.divide(base, MathContext.DECIMAL128)) == 1);
  308.  
  309.             Numerowo.numeroFinal = doblarCadena(Numerowo.numeroFinal);
  310.  
  311.             if (Numerowo.Fraccional) {
  312.                 int infinidad = 0;
  313.  
  314.                 BigDecimal comparandum = new BigDecimal("0.0000000000000000000001");
  315.  
  316.                 Numerowo.numeroFinal += ".";
  317.  
  318.                 byte resto;
  319.  
  320.                 do {
  321.                     resto = F.multiply(base).byteValue();
  322.  
  323.                     F = F.multiply(base).subtract(BigDecimal.valueOf(resto));
  324.  
  325.                     Numerowo.numeroFinal += Numerowo.Caracteres0Z[resto];
  326.  
  327.                     infinidad++;
  328.  
  329.                 } while (F.compareTo(comparandum) == 1 && infinidad < Numerowo.maxFlotantes);
  330.             }
  331.         }
  332.     }
  333.  
  334.     static String doblarCadena(String Cadena) {
  335.  
  336.         String anedaC = "";
  337.  
  338.         for (int b = Cadena.length() - 1; b >= 0; b--) {
  339.             anedaC += Cadena.charAt(b);
  340.         }
  341.  
  342.         return anedaC;
  343.     }
  344.  
  345.     public static void main(String[] args) {
  346.  
  347.         llenarCaracteres();
  348.  
  349.         pedirDatums();
  350.  
  351.         obtenerDecimal();
  352.  
  353.         obtenerConvertido();
  354.  
  355.         System.out.println(Numerowo.numeroFinal);
  356.  
  357.     }
  358. }
RAW Paste Data