silverfrost plato para mega mac instalar for como fortran gfortran fortran95

para - plato fortran 95



Fortran 95 recogiendo por su cuenta (2)

Decidí aprender el idioma fortran95 (por lo que no es importante). Sin embargo, siendo un principiante, me encontré con un problema extraño que realmente no puedo explicar, por lo tanto, necesito ayuda.

Tengo el algoritmo de ordenación de inserción:

subroutine insertion_sort_REAL4(array, array_len) implicit none !parameners integer :: array_len real (kind=4), dimension(array_len) :: array !variables integer :: i,key,hole_pos do i = 0,array_len key = array(i) hole_pos = i; do while ((hole_pos > 0.0) .and. (key < array(hole_pos - 1))) array(hole_pos) = array(hole_pos - 1) hole_pos = hole_pos - 1 end do array(hole_pos) = key end do return end

Y está el programa principal (extracto):

real (kind = 4), dimension(3) :: x x(1) = 3.1 x(2) = 4.3 x(3) = 5.4 write(*,*) ''Array = '',x call insertion_sort_REAL4(x,3) write(*,*) ''Array = '',x

Se imprime la primera declaración de write

Array = 3.09999990 4.30000019 5.40000010

¿Por qué los números han sido ligeramente modificados? ¿Fortran95 no usa el estándar IEEE754 por defecto?

Pero digamos que puedo vivir con la ligera alteración; las segundas instrucciones de write imprimen

Array = 3.00000000 4.00000000 5.00000000

¿Por qué los números han sido redondeados? Realmente me está molestando y el formateo de la declaración de "escritura" no está funcionando bien y las búsquedas de Google realmente no me han ayudado. Supongo que no hay muchas cosas en Internet sobre Fortran como lo es de C. Soy un programador decente de C por lo que se agradecen todos los paralelismos. Gracias por tu ayuda!


Es probable que un número decimal como "3.1" no tenga una representación exacta en un número binario de longitud finita. El enunciado del código fuente x(1) = 3.1 hace que la computadora convierta ese número decimal en binario y lo almacene. La instrucción write (*, *) x(1) hace que la computadora obtenga este valor binario y lo convierta a decimal. Debido a que "3.1" no se pudo representar exactamente en el binario de longitud finita, la conversión a decimal no recupera precisamente "3.1". Esto explica el resultado de "3.09999990". Esto no es específico de Fortran, sino aritmética de coma flotante de precisión general a finita.

En cuanto al otro problema, la key se declara como un entero en la subrutina de ordenamiento y, por lo tanto, se redondean los reales en enteros. Cuando compilé su programa con las advertencias completas del compilador activadas, gfortran me lo notificó.

Si te gusta, prueba las siguientes opciones de compilación: -O2 -fimplicit-none -Wall -Wline-truncation -Wcharacter-truncation -Wsurprising -Waliasing -Wimplicit-interface -Wunused-parameter -fwhole-file -fcheck=all -std=f2008 -pedantic -fbacktrace . También encontrará que su programa tiene un error de subíndice.


Para la primera parte : usa IEEE754 , y esa es la razón por la cual los números se "cambian".

Lo que todo científico informático debería saber sobre el artículo de aritmética de punto flotante es una lectura obligada para comprender cómo funciona esto, y también hay buenas calculadoras IEEE754 ...

Entonces 3.1 nunca fue exactamente 3.1 , pero

3.0999999046325684

en primer lugar.

En cuanto a la segunda parte : no se redondean sino que se convierten en enteros, pero no estoy en Fortran, así que supongo que algo se declara como int en la rutina insertion_sort_REAL4 , que hace que los números se conviertan en enteros.