es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Si no se admite el tipo de dato double, ¿cómo puedo utilizar float para lograr la misma precisión?

Tengo un código en C que hace lo correcto como deseo.

void create_weights(float alpha, float beta, float kappa, uint8_t L){

    /* Calcular los parámetros lambda y gamma */
    double lambda = alpha * alpha * (L + kappa) - (double)L;

    /* Insertar en el primer índice */
    float Wm0 = lambda/(L + lambda);
    float Wc0 = Wm0 + 1 - alpha * alpha + beta;

    printf("Wm0 = %f, Wc0 = %f, lambda = %f\n", Wm0, Wc0, lambda);
    printf("Wci = 0.5f / (L + lambda) = %f\n",0.5f / (L + lambda));
}

int main() {

    create_weights(0.001, 2, 0, 3);

    return 0;
}

La salida es:

Wm0 = -999998.875000, Wc0 = -999995.875000, lambda = -2.999997
Wci = 0.5f / (L + lambda) = 166666.648140

En MATLAB, la salida es:

lambda = -2.999997000000000
Wm0 = -999999.0000082518 
Wc0 = -999996.0000092518
0.5 / (L + lambda) = 166666.6666680420

¡Así que estoy muy cerca! Pero aquí está el problema. Esta línea:

double lambda = alpha * alpha * (L + kappa) - (double)L;

Como puedes ver, he mezclado “double” y “float”. Es solo para la prueba.

Si cambio ese código a:

double lambda = alpha * alpha * (L + kappa) - L;

O este código (ahora solo hay floats en el código):

float lambda = alpha * alpha * (L + kappa) - L;

Entonces obtendré esta salida:

Wm0 = -967915.312500, Wc0 = -967912.312500, lambda = -2.999997
Wci = 0.5f / (L + lambda) = 161319.384615

Así que en este caso, necesito esta línea, pero no se me permite usar “double” porque mi procesador no lo soporta.

¿Qué puedo hacer si quiero la misma precisión de punto flotante con “double”, como en “float”?

Ejecuta el código aquí:
https://onlinegdb.com/dwwWtdf2S

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Una solución sería utilizar una representación de punto fijo en lugar de punto flotante. La aritmética de punto fijo permite cálculos más precisos que el punto flotante, sin la sobrecarga de doble precisión.

    En la aritmética de punto fijo, los números se representan como enteros con un número fijo de decimales. Por ejemplo, si utilizamos una representación de punto fijo con 12 decimales, el número 1.0 se representaría como 1000000000000.

    Para convertir los valores de entrada (alfa, beta, kappa, L) a punto fijo, los multiplicaríamos por un factor de escala (por ejemplo, 10^12 para 12 decimales) y los almacenaríamos como enteros. Por ejemplo, si alfa = 0.001 y usamos 12 decimales, almacenaríamos alfa_escalado = 1000000.

    Luego, en el código, realizaríamos los cálculos utilizando aritmética de punto fijo. Por ejemplo:

    int32_t lambda = (int32_t)(alfa_escalado * alfa_escalado * (L_escalado + kappa_escalado) - L_escalado);
    

    Aquí, utilizamos int32_t para representar los valores de punto fijo con 12 decimales.

    Finalmente, dividiríamos los resultados de salida por el factor de escala para obtener los valores correctos en representación de punto flotante.

    Este enfoque es más complejo y requiere un esfuerzo adicional para la conversión y escalamiento, pero nos permite obtener la misma precisión que el doble con flotante, sin requerir soporte de doble precisión del procesador.

Comments are closed.