Pregunta

Estoy tratando de trabajar con números grandes (~10^14), y necesito poder almacenarlos e iterar sobre bucles de esa longitud, es decir,

n=SOME_BIG_NUMBER
do i=n,1,-1

Probé la notación de estrellas habitual, kind=8 etc.Pero nada parece funcionar.Luego revisé el huge función intrínseca, y el código:

program inttest

print *,huge(1)
print *,huge(2)
print *,huge(4)
print *,huge(8)
print *,huge(16)
print *,huge(32)

end program inttest

produce el número 2147483647 en todos los casos.¿Por qué es esto?Estoy usando gfortran (f95) en una máquina de 64 bits.

Si voy a necesitar una biblioteca bignum, ¿cuál sugiere la gente?

¿Fue útil?

Solución

Las versiones de GFORRAN que yo uso, 4.3, 4.4 y 4.5 en una MAC, soportan enteros de 8 bytes. La mejor manera de seleccionar un tipo variable en FORTRAN>= 90 es usar una función intrínseca para especificar la precisión que necesita. Prueba:

integer, parameter :: LargeInt_K = selected_int_kind (18)
integer (kind=LargeInt_K) :: i, n

para obtener al menos 18 dígitos decimales, que normalmente serán un entero de 8 bytes.

con GFORRAN 4.3, enormes (1_largeint_k) Salidas 9223372036854775807. Cuando escribió enorme (1), etc., por defecto, la constante fue un entero predeterminado, aquí evidentemente 4 bytes desde que se devolvió 2147483647., por lo que a veces necesitas especificar La precisión de las constantes, no solo las variables, más comúnmente, los viajes a las personas se levantan cuando pierden figuras significativas en una constante real, lo que por defecto es una precisión única.

También vea FORTRAN: INTEGER * 4 VS INTEGER (4) VS entero (tipo= tipo= 4)

Por lo general, GFORTRAN tiene el nombre del comando GFORTRAN. ¿Podría F95 ser un compilador diferente? Pruebe "GFORRAN -V" y "F95 -V".

Otros consejos

Has entendido mal la definición precisa de HUGE función. HUGE(num) devuelve el número más grande con el mismo tipo y tipo que num.El valor devuelto también tiene el mismo tipo y tipo que num.Dado que todos sus valores de entrada son enteros (predeterminados) HUGE, correctamente, devuelve el mayor número entero de tamaño predeterminado.

HUGE(num) no devuelve el entero más grande con kind=num.Ni tampoco HUGE(num) devolver el mayor número representable en num bytes.Si bien muchos compiladores usan integer(kind=4) y integer(kind=8) etc. para enteros de 4 y 8 bytes, esto no está garantizado por el estándar del lenguaje y no se puede confiar en que sea portátil.

La respuesta de @MSB te dice cómo hacer lo que quieres, solo estoy interviniendo con algunas aclaraciones.

Resumen: Considere mirar las opciones del compilador.

Ha sido un tiempo L-O-N-G desde que he hecho Fortran, y no recuerdo que estoy usando enorme (), pero miré esto un poco. Mi máquina Intel Linux tiene GFORTRAN 4.1.2. Descubrí que tenía que compilar con la opción -fdefault-enter-8 encendida para que funcione para los enteros de 64 bits. Específicamente, con este código:

      program inttest
      print *, huge(1)
      end program inttest

corriendo

$ GFORRAN INTTEST.FOR

Creado un ejecutable que imprimió:

2147483647

Sin embargo, ejecutando:

$ GFORTRAN -FDEFAULT-INTEGER-8 INTTEST.FOR

dio lugar a un ejecutable que dio la salida:

9223372036854775807

Además, cuando declaré una variable como entero * 8 y compilada sin la opción -fdefault-enteger-8, obtuve un error. El código:

  program inttest2
  integer*8  test_int
  test_int = 9223372036854775807
  print *, test_int
  end program inttest2

corriendo

$ GFORRAN INTTEST2.Por

resultó en

en el archivo inttest.for: 4

  test_int = 9223372036854775807  
                               1 

Error: entero demasiado grande para su tipo en (1)

Sin embargo, las cosas funcionaban bien cuando compilié con la opción -fdefault-integer-8 y obtuve un ejecutable que imprimió

9223372036854775807

Tal vez haya otras opciones de Gforterán que serían útiles, pero no investigamos más adelante.

concedida, esto todavía no lo consigue 10 ^ 14, pero puede ayudar a explicar los resultados que vio.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top