سؤال

أحاول العمل بأعداد كبيرة (~10^14)، وأحتاج إلى أن أكون قادرًا على تخزينها وتكرارها عبر حلقات بهذا الطول، أي.

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

لقد جربت تدوين النجمة المعتاد، kind=8 إلخ.لكن يبدو أن لاشئ يعمل.ثم قمت بفحص huge الوظيفة الجوهرية والرمز:

program inttest

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

end program inttest

ينتج الرقم 2147483647 في جميع الحالات.لماذا هذا؟أنا أستخدم gfortran (f95) على جهاز 64 بت.

إذا كنت سأحتاج إلى مكتبة كبيرة، فما هي المكتبة التي يقترحها الناس؟

هل كانت مفيدة؟

المحلول

إصدارات gfortran التي أستخدمها، 4.3 و4.4 و4.5 على جهاز Mac، تدعم الأعداد الصحيحة ذات 8 بايت.أفضل طريقة لتحديد نوع متغير في Fortran >= 90 هي استخدام دالة جوهرية لتحديد الدقة التي تحتاجها.يحاول:

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

للحصول على 18 رقمًا عشريًا على الأقل، والذي سيكون عادةً عددًا صحيحًا مكون من 8 بايت.

مع gfortran 4.3، تكون المخرجات الضخمة (1_LargeInt_K) 9223372036854775807.عندما كتبت ضخمًا (1)، وما إلى ذلك، كان الثابت افتراضيًا هو عدد صحيح افتراضي، ومن الواضح هنا أن 4 بايت منذ أن عاد ضخم 2147483647.لذلك في بعض الأحيان تحتاج إلى تحديد دقة الثوابت، وليس فقط المتغيرات - والأكثر شيوعًا أن هذا يؤدي إلى تعثر الأشخاص عندما يفقدون أرقامًا كبيرة على ثابت حقيقي، والذي يتم تعيينه افتراضيًا على دقة واحدة.

انظر أيضا فورتران:عدد صحيح * 4 مقابل عدد صحيح (4) مقابل عدد صحيح (نوع = 4)

عادةً ما يكون لـ gfortran اسم الأمر gfortran.هل يمكن أن يكون f95 مترجمًا مختلفًا؟جرب "gfortran -v" و"f95 -v".

نصائح أخرى

لقد أخطأت في فهم التعريف الدقيق لل HUGE وظيفة. HUGE(num) تقوم بإرجاع أكبر رقم بنفس النوع والنوع num.القيمة التي تم إرجاعها لها أيضًا نفس النوع والنوع num.نظرًا لأن جميع قيم الإدخال الخاصة بك هي أعداد صحيحة (افتراضية). HUGE, بشكل صحيح، تُرجع أكبر عدد صحيح بالحجم الافتراضي.

HUGE(num) لا يُرجع أكبر عدد صحيح مع kind=num.ولا كذلك HUGE(num) إرجاع أكبر عدد يمكن تمثيله في num بايت.بينما يستخدم العديد من المترجمين integer(kind=4) و integer(kind=8) إلخ بالنسبة للأعداد الصحيحة ذات 4 و8 بايت، لا يضمن معيار اللغة ذلك ولا يمكن الاعتماد عليه ليكون محمولاً.

تخبرك إجابة @MSB بكيفية القيام بما تريد، أنا فقط أقدم بعض التوضيحات.

ملخص:النظر في النظر في خيارات المترجم.

لقد مر وقت طويل منذ أن قمت باستخدام لغة FORTRAN، ولا أتذكر استخدام HUGE()، لكنني نظرت إلى هذا قليلاً.يحتوي جهاز Intel Linux الخاص بي على gfortran 4.1.2.لقد وجدت أنني اضطررت إلى الترجمة مع تشغيل الخيار -fdefault-integer-8 لجعله يعمل مع أعداد صحيحة 64 بت.على وجه التحديد، مع هذا الرمز:

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

جري

$ gfortran inttest.for

أنشأ ملفًا قابلاً للتنفيذ والذي طبع:

2147483647

ومع ذلك، تشغيل:

$ gfortran -fdefault-integer-8 inttest.for

أدى إلى ملف قابل للتنفيذ والذي أعطى الإخراج:

9223372036854775807

أيضًا، عندما أعلنت عن متغير كعدد صحيح*8 وقمت بتجميعه بدون الخيار -fdefault-integer-8، حصلت على خطأ.الرمز:

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

جري

$ gfortran inttest2.for

أسفرت

في الملف inttest.for:4

  test_int = 9223372036854775807  
                               1 

خطأ:عدد صحيح كبير جدًا بالنسبة لنوعه عند (1)

ومع ذلك، سارت الأمور بشكل جيد عندما قمت بالتجميع باستخدام الخيار -fdefault-integer-8 وحصلت على ملف قابل للتنفيذ تمت طباعته

9223372036854775807

ربما تكون هناك خيارات gfortran أخرى قد تكون مفيدة، لكنني لم أقم بالتحقيق فيها أكثر.

من المؤكد أن هذا لا يمنحك 10^14، ولكنه قد يساعد في تفسير النتائج التي رأيتها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top