PI-ITBA / 2024_01

8 stars 0 forks source link

tp8_ej6 #163

Closed matsdah closed 3 months ago

matsdah commented 5 months ago

Buenas tardes, como les va? Queria consultar si el ejercicio esta bien resuelto, o si por otro lado habria que hacer alguna correccion.

Tengo mis dudas en la funcion buscaRaices con respecto al sizeof, en donde hago un realloc para las raices de la respuesta. Queria preguntarles que tamaño deberia asignarle a cada raiz (intervalo [a, b]); si es el tamaño de un puntero, o el tamaño de la estructura tipoIntervalo.

A continuacion les dejo el codigo y un screenshot de la salida. Desde ya les agradezco la atencion.


#include "../Libraries/getnum.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#define FUNCION(x) (sin(x))
#define ERROR 0.00001
#define PARTICIONES 100000
#define BLOQUE 10
#define TRUE 1
#define FALSE !TRUE

typedef struct{
    float intervaloIzq;
    float intervaloDer;
} tipoIntervalo;

typedef struct{
    int dim;
    tipoIntervalo *raices;
} tipoResp;

tipoResp buscaRaices(tipoIntervalo intervalo);
int esRaiz(float i, float incremento);

int main(){
    tipoIntervalo intervalo;
    intervalo.intervaloIzq = getfloat("Ingresar intervalo izquierdo: ");
    do{
        intervalo.intervaloDer = getfloat("Ingrese intervalo derecho: ");
    } while(intervalo.intervaloDer <= intervalo.intervaloIzq);
    tipoResp resp = buscaRaices(intervalo);

    printf("Se han encontrado %d raices.\n", resp.dim);
    for(int i = 0; i < resp.dim; i++) {
        printf("{%f, %f}\t", resp.raices[i].intervaloIzq, resp.raices[i].intervaloDer);
    }

    free(resp.raices);
    return 0;
}

tipoResp buscaRaices(tipoIntervalo intervalo){
    tipoResp resp;
    float anterior, proximo;
    resp.dim = 0;
    resp.raices = NULL;
    float incremento = (intervalo.intervaloDer - intervalo.intervaloIzq) / PARTICIONES;
    if(incremento == 0){
        incremento = ERROR;
    }
    for(float i = intervalo.intervaloIzq; i <= intervalo.intervaloDer; i += incremento){
        if(esRaiz(i, incremento)){
            anterior = i - incremento;
            if(resp.dim % BLOQUE == 0){
                resp.raices = realloc(resp.raices, (resp.dim + BLOQUE) * sizeof(resp.raices));
            }
            do{
                proximo = (i += incremento);
            } while(esRaiz(i, incremento));
            resp.raices[resp.dim].intervaloIzq = anterior;
            resp.raices[resp.dim].intervaloDer = proximo;
            resp.dim++;
        }
    }
    resp.raices = realloc(resp.raices, resp.dim * sizeof(resp.raices));
    return resp;
}

int esRaiz(float i, float incremento){
    if((fabs(FUNCION(i)) < ERROR) || (FUNCION(i) * FUNCION(i + incremento) < 0)){
        return TRUE;
    }
    return FALSE;
}

Codigo de salida (seno como funcion utilizada):

Captura de pantalla 2024-05-06 161155

ImNotGone commented 5 months ago

deberia ser sizeof(tipoIntervalo) o sizeof(*resp.raices), donde usas lo de incremento = ERROR? en el do while no te intereza permanecer dentro del limite?

matsdah commented 5 months ago

Gracias por la alcaracion del sizeof. Por que es que funciona igualmente con sizeof(resp.raices)? Es casualidad?

Lo de incremento = ERROR es por si PARTICIONES es muy grande e incremento quede como 0 y no entre en un loop. En realidad puse ERROR para no dejar una constante simbolica. En el do while no me interesa permancer dentro del limite porque el ejercicio me pide que guarde los valores inmediatamente anteriores y posteriores de la raiz.

ImNotGone commented 5 months ago

los punteros en muchas arquitecturas son de 8 bytes. Podes fijarte cuanto es en la tuya haciendo

char a;
int b;
printf("%d %d\n", sizeof(&a), sizeof(&b));

Como el tamanio del puntero es indistinto del tipo esto te deberia dar "8 8".

Los structs se alinean a 4 bytes, es decir si tenes

struct {
char a;
int b;
}

ocupa 8 bytes por mas de que a ocupe 1 y b ocupe 4

En este caso tenes 2 floats, que ocupan 4 y 4 por lo cual ya esta alineado a 4 bytes y ocupa 8, lo mismo que un puntero. Pero conceptualmente lo que pusiste esta mal

lo de incremento en 0 sigo sin entenderlo, pq no esta en la codicion del for ni nada, pq decis q saltea el loop?

matsdah commented 5 months ago

Muchas gracias por la respuesta, se que no es horario de consultar, asi que agradezco el compromiso.

Claro, entiendo perfecto el alineamiento en tu ejemplo. Tambien no estaba contemplando que los punteros pueden ocupar 8 bytes, con el programa que proporcionaste lo corrobore.

Concretamente en el ejercicio, yo en cada realloc tengo que reservarle a resp.raices (puntero a tipoIntervalo) el tamanio de la estructura tipoIntervalo: es decir a lo que apunta y no el tamanio del puntero. Si es asi, quedaria concluida la consulta.

ImNotGone commented 5 months ago

siempre cuando estas reservando memoria para un puntero desreferencialo, en criollo sacale una *, lo que te queda es lo que va en el sizeof. si tenes int * a -> dimsizeof(int*). Despues para cada uno de esos punteros a int probablemente tendrias q reservar

for (int i = 0; i < dim; i++) {
a[i] = malloc(dim_interior*sizeof(int)); // el tipo de a[i] es int * pq ya desreferencie con el [i], si desreferencio denuevo queda int (eso va en el sizeof)
}

si tenes tipo_x -> dimsizeof(tipo_x).

Cualquier cosa consulta