Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - RayR

#11
Cita de: snoopty en  9 Septiembre 2021, 00:30 AM
Gracias. Pero no, tengo la PC en bucle con Pantalla Azul al arrancar.....( ¿ Dev-C++ Embarcadero; o cualquier .cpp y su .exe generado pudieron haber generado esta Imposibilidad de arranque ?? ) estoy desde Apps Cxx y Dcoder ( Android ) y no funciona.
Existe algo de esto para las Apps ( ? )
Saludos !

No vi eso. Lo que te puse aplica sólo para Windows. No sé cómo sea la terminal de Android que uses, pero se usa UTF-8 igual que en Linux, por lo que quizás algo así te pudiera funcionar:


Código (cpp) [Seleccionar]
setlocale(LC_ALL, "es-ES.UTF-8")
wcin.imbue(locale("es-ES.UTF-8"));
wcout.imbue(locale("es-ES.UTF-8"));


Y usarías las funciones y tipos "wide" para manejar texto. En lugar de cout, cin, string y char, usarías wcout, wcin, wstring, wchar_t, etc. Pero yo nunca trabajo de esta manera en la terminal, así que no sé si te sirva.

Pensándolo mejor, aunque usar las funciones wide hace más explícito el hecho de que en Unicode los caracteres pueden ocupar varios bytes (lo cual pensé que te podría evitar errores), creo que al final podría ser más confuso, por lo que igual puedes aplicar el imbue a cin y cout y seguir usándolos sin tener que lidiar con wcout y demás. De cualquier forma, no deberás usar variables char simples sino arreglos char o directamente string, aún si únicamente quieres leer un solo caracter.
#12
Siempre es un dolor de cabeza trabajar con localización, sobre todo en Windows. No está mal como lo estabas haciendo, pero debes asegurarte de que la consola use la misma codificación. Cuando usas "Spanish" o "es-ES" para el locale, en realidad es como si pusieras "Spanish_Spain.1252". O sea estás configurando el código de página ANSI 1252, pero, si no recuerdo mal, la consola usa una codificación OEM, por lo que eñes y acentos no van a salir bien. Necesitas cambiar también la consola:

Código (cpp) [Seleccionar]

setlocale(LC_ALL, "es-ES");
/* O bien
setlocale(LC_ALL, "Spanish_Spain");
o
setlocale(LC_ALL, "Spanish_Spain.1252");
*/

// Cambia la salida
SetConsoleOutputCP(1252);

// Y la entrada
SetConsoleCP(1252);


Sin embargo, aunque ahora mismo no tengo donde probarlo, estoy casi seguro de que la fuente que usaba por defecto la consola en Windows 7 no tenía eñes ni acentos para esa codificación, por lo que si quieres que funcione en esa versión o anteriores debes asegurarte de cambiarla.

Alternativamente, puedes poner el locale a OEM:
Código (cpp) [Seleccionar]

// O "Spanish_Mexico.850", "Spanish_Argentina.850", etc
setlocale(LC_ALL, "Spanish_Spain.850");
// Es buena idea asegurarse de que la consola esté igual
SetConsoleOutputCP(850);
SetConsoleCP(850);


esto me parece que no tiene el problema de las fuentes en versiones anteriores de Windows, pero es más recomendable la forma anterior.

Esto aplica para los valores que se muestran y leen en la consola, pero no significa que los caracteres especiales que escribas en tu código se muestren correctamente. Eso depende de la codificación que use el editor con el que lo escribes, por lo que es muy mala idea usar este tipo de caracteres en el código (si lo abres en otro editor, o en el mismo editor pero en otra máquina o sesión, te lo va a descomponer). Una forma más portable es usar sus valores numéricos:

Código (cpp) [Seleccionar]

//Para ANSI 1252
cout << "Ingrese la Letra 'E""\xF1""E'" << endl;
//Para OEM 850
cout << "Ingrese la Letra 'E""\xA4""E'" << endl;


hay formas mucho mejores de manejar la localización, pero también son más complicadas. Para cosas simples yo creo que con esto basta.
#13
Cita de: **Aincrad** en  4 Septiembre 2021, 21:23 PM
Hola, gracias por responder.

La idea era hacerlo directamente en un solo ejecutable. y al final lo logre de la misma manera que lo hace ProcessHacker2.

Básicamente se ejecuta a si mismo mediante runas y con líneas de comandos sabe que función ejecutar.

Pues esa es la forma tradicional de hacerlo, pero justamente implica lanzar un nuevo proceso, que pensé que era algo que no querías, así que supuse que ya la conocías pero buscabas otra manera. Imaginé que necesitarías comunicación hacia y desde la parte privilegiada, y de ahí lo que mencioné de IPC.

La alternativa del componente COM, aunque tiene sus inconvenientes, como todo, tiene la gran ventaja de que, aunque técnicamente el componente se ejecutaría en un proceso subrogado (por defecto, dllhost), COM se encarga de los detalles de la comunicación, por lo que uno se limita a llamar funciones, pasar parámetros y recibir resultados prácticamente de la misma manera en que lo haría con cualquier programa normal.

Pero sí, cuando sólo se necesita cosas más sencillas como ejecutar tareas más o menos independientes, la forma en que lo hiciste es la más simple y recomendable
#14
Cita de: snoopty en 25 Agosto 2021, 06:46 AM
Gracias por responder.
Entonces, es definitivo el hecho de que " NO ES CORRECTA " la cantidad de decimales de tipo float ( según la Teoría, 7 decimales ) , double (15) y long double ( 19 ) que se puede mostrar como resultado de una operación ?

Así es, no es correcto eso. Me voy a centrar en los float por simplificar, pero esto aplica para los otros tipos.

Lo que pasa es que en muchas páginas utilizan incorrectamente la fórmula log10(224) (el 24 es porque los float tienen un signifcando de 23 bits +  1 implícito), lo cual da 7.22, de lo que se puede suponer que en un float caben todos los números de 7 dígitos y algunos de 8, pero eso es falso, ya que hay números con 7 que no se pueden representar. Incluso, hay algunos flotantes que requieren 9 dígitos decimales para mostrarse correctamente. Y es que esa fórmula sirve para enteros pero no para flotantes, que son más complicados, y no aumentan consecutivamente de unidad en unidad, y hay rangos en los cuales el salto entre números consecutivos es mucho más grande que en otros. Básicamente, con flotantes, esa fórmula nos dice en cuántos dígitos decimales cabe el significando (si lo tratamos como entero), lo cual no es de mucho interés. Lo que queremos es saber los dígitos del número en sí, pero la fórmula no nos dice nada al respecto. Tenemos 224 valores distintos para el significando, sí, pero la cuestión es cómo se distribuyen los números que se pueden representar a partir de ese significando.

Imagina un formato en el cual almacenamos enteros como potencias positivas de 2, usando 4 bits. Así, 64 se almacenaría como 0110, porque 64 = 26. La fórmula nos diría que tenemos 1.20 dígitos, pero el número mayor que podemos almacenar es 215 = 32768, que tiene 5 dígitos. Y es que la fórmula sólo nos dice los dígitos de la potencia almacenada (igual que hace con el significando en los flotantes) pero no del número (de nuevo, como tampoco lo hace con los flotantes y por eso no nos sirve).

En cuanto a tu código, primero, el sufijo 'i' no existe en C++. GCC y compiladores basados en él lo agregan como extensión pero no deberías usarlo porque no es portable. De todas formas, la 'i' indica la parte imaginario de un número complejo, y el programa no sabe cómo interpretarlo. Pon un #include <ccomplex>.

Lo demás es lo que ya te había puesto en mi otro mensaje. No tiene mucho sentido preguntarse cuántos dígitos decimales puede almacenar un flotante. Si acaso, puedes contar con que un float represente correctamente números de hasta 6 dígitos significativos (15 en el caso de double). Arriba de eso, depende. Pero además resulta que "representar correctamente" no necesariamente significa que se almacene de forma exacta, sino que al convertirlo nuevamente a decimal para mostrarse, luego de redondearse, sus primeros 6 dígitos serán iguales al número introducido originalmente. Es lo que pasa con tu código. Lo que se está almacenando son aproximaciones a los números. Sólo se guardan de forma "exacta" los primeros "n" dígitos (de nuevo, ese valor "n" depende del tipo, f ó d, y del número en sí). Si intentas imprimir con una precisión mayor, se muestran dígitos adicionales, que no van a coincidir con los que escribiste. Revisa de nuevo el ejemplo de mi mensaje anterior para ver por qué.
#15
La forma en que se representan los números de punto flotante no es específica de C++. En realidad es un estándar que prácticamente todos los lenguajes actuales siguen, aunque puede haber ciertas variaciones.

Primero aclarar que cuando se habla de dígitos significativos, esto se refiere a todos ellos, no sólo la parte decimal (1.25 tiene 3 dígitos significativos). Dicho esto, no se puede hablar de forma exacta de cuántos de ellos en decimal puede almacenar un flotante, ya que esto varía. No basta con ver la cantidad de bits que se usan, ya que los valores que se pueden representar no están distribuidos de manera uniforme. Hay muchos números con 7 dígitos significativos que no se pueden almacenar de forma exacta en precisión simple (float). Por otro lado, hay algunos con más de 7 (como 16777216) que sí se pueden representar perfectamente.

Además de esto, y dado que los flotantes se almacenan en binario, hay números que simplemente no se pueden representar de forma exacta (como 0.1) independientemente del número de bits que se usen.

En cuanto a tus dudas concretas, cuando imprimes el float con cout, de forma predeterminada se usa una precisión de 6 dígitos. Si parece que se están usando menos es simplemente porque el número se está redondeando. Cuando aumentas la precisión de salida, se están mostrando algunos números distintos porque tu número no se pudo guardar de forma exacta en su representación binaria; sólo se almacenó un valor aproximado, y al convertirlo de vuelta a decimal, es posible que el resultado tenga más dígitos que el original. Los detalles exactos son complicados, pero va un ejemplo inventado que puede ayudar a entender esto.

Imagina que quisiéramos almacenar números en forma de fracción, guardando númerador y denominador. Así, 1.5 se podría almacenar como 3/2. Un número como 1.1428 se podría guardar como 8/7, que no es exacto, pero sí una "buena" aproximación. Naturalmente, para convertirlo de vuelta a decimal, dividimos 8 entre 7, pero fíjate que 8/7 es periódico, por lo que la división se podría continuar hasta el infinito. En realidad lo que hacemos es detenernos al llegar a la precisión deseada. Si queremos imprimirlo con 5 dígitos dividimos hasta que tenemos 1.1428. Si en cambio quisiéramos 7 dígitos, obtendríamos 1.142857, y así sucesivamente. No es que el número se esté rellenando con cifras inventadas, es simplemente que lo que guardamos es una aproximación que al convertirse de vuelta nos da más dígitos que el valor original que queríamos almacenar.

Hay más detalles que pueden alterar el valor mostrado, como que al hacer conversiones se podrían utilizar bits adicionales de forma intermedia, y que se pueden aplicar distintos tipos de redondeo, pero creo que ya sería complicarse demasiado y no hace falta para entender de forma general lo que está pasando.
#16
Programación C/C++ / Re: Puntero doble
16 Agosto 2021, 03:34 AM
Si tienes algún manual de C, revisa bien la sección de punteros, porque sigues confundiendo mucho las cosas. A lo que me refiero con mi mensaje anterior es a que cuando tienes una variable ptr que es un puntero a puntero (o puntero doble como dices), debes inicializar tanto a ptr como a *ptr. Para este ejemplo, eso significa que necesitas dos llamadas a malloc, cada una reservando el espacio necesario y haciendo el cast al tipo correspondiente para cada puntero. No estás haciendo ninguna de esas cosas en la línea 25, y además, dado que nuevo es un puntero a puntero, lo estás desreferenciado mal ( (*nuevo)->campo es la manera correcta).  De cualquier forma te estás complicando más de lo necesario, ya que nuevo no necesita ser un puntero a tNodo. Simplemente cambia la línea 25 a:

tNodo nuevo = (tNodo)malloc(sizeof(struct rNodo));

y la 28 a

*ppio = nuevo;
#17
Programación C/C++ / Re: Puntero doble
15 Agosto 2021, 18:46 PM
Aquí también tienes un error:

(*nuevo_elemento)->contenido.DNI = nuevoDato->DNI;

porque reservaste memoria para nuevo_elemento, pero no para *nuevo_elemento, por lo que este último es un puntero sin inicializar, así que en la línea anterior estás escribiendo en quién sabe que dirección. Antes tienes que hacer algo como esto:

*nuevo_elemento = (COLA)malloc(sizeof(tCola));

De todas formas, piensa bien si de verdad necesitas tantas indirecciones. Puedes pasar variables por puntero/referencia sin usar realmente un puntero, simplemente usando el operador &. Fíjate a ver si puedes simplificar tu programa.
#18
No probé el programa, pero tienes un error en la línea 62:

   GENERATED_IV = IV;

IV es local a la función cipherBlock, por lo que sólo existe dentro de ella (de hecho, dentro del bloque if donde fue declarada) de manera que al retornar de esa función, GENERATED_IV apunta a una dirección inválida. Es de esas cosas que a veces funcionan por casualidad pero son un error. Probablemente eso es lo que te ocasiona el problema. También por ahí reservas memoria sin liberarla pero eso aquí sólo gasta memoria y no es la causa del error.

Añado: lo más simple sería que hagas GENERATED_IV un arreglo de tamaño fijo.
#19
Cita de: tca153 en  8 Agosto 2021, 16:29 PM
gracias para empezar soy nuevo en linux, a que funciones especificas te referis, y por otra parte, estamos de acuerdo que esa zona de memoria igual que la 0xA0000000, siguen existiendo?, si es asi no hay ninguna manera de romper esa barrera sin dañar al SO?

Esas direcciones en sí no tienen nada de especial, es simplemente que bajo DOS, ahí se mapeaba la VRAM. Escribir en esas direcciones para modificar los pixeles o caracteres sólo tiene sentido bajo DOS o algún SO compatible, y con la tarjeta de video corriendo en modo EGA, VGA, etc. De todas formas los sistemas modernos usan memoria virtual, por lo que la dirección 0xb8000000 que ve tu programa no se corresponde con la dirección física 0xb8000000 en la RAM. Además, en general no permiten acceder directamente al hardware a los programas normales.

TL;DR: no se puede de esa manera. BloodSharp ya te dio algunas opciones con las que lo podrías hacer.
#20
Como te dijo BloodSharp , eso es para el viejo DOS. No sirve para sistemas operativos modernos, por muchas razones. Que te funcionara en Windows se explica porque las versiones de 32 bits incluyen (o por lo menos así era antes) una máquina virtual de DOS para los programas de 16 bits, por lo que si el ejecutable fue generado con un compilador de 16 bits, y lo abres en esas versiones de Windows, va a funcionar, aunque de forma emulada, no nativa. Si de todas formas te interesa programar de esa manera por curiosidad, puedes instalar el emulador DOSBox, que tiene versiones para Windows y Linux, pero lo mejor es que simplemente uses funciones específicas del SO.