Как мне присвоить целое число boz-literal-constant Z'FEDCBA09'
или любой другой битовый шаблон с старшим значащим битом, равным 1?
Стандартные состояния:
INT(A[,KIND])
: Если A
является буквенной константой boz, значением результата является значение, чья битовая последовательность в соответствии с моделью в 16.3 такая же, как у Aизмененный дополнением или усечением в соответствии с 16.3.3. Интерпретация битовой последовательности, старший бит которой равен 1., зависит от процессора.
источник: Стандарт Fortran 2018
Таким образом, следующие назначения могут потерпеть неудачу (предположим, integer
является 32-битным по умолчанию):
program boz
implicit none
integer :: x1 = int(Z'FEDCBA09')
integer :: x2 = int(Z'FFFFFFFF')
integer :: x3
data x3/Z'FFFFFFFF'/
end program
При использовании gfortran это будет работать только тогда, когдадобавление -fno-range-check
, но это приводит к дополнительным нежелательным эффектам:
-fno-range-check
: отключить проверку диапазона для результатов упрощения константных выражений во время компиляции. Например, GNU Fortran выдаст ошибку во время компиляции при упрощении a = 1. / 0.
. При использовании этой опции ошибка не будет отображаться, и ей будет присвоено значение + Бесконечность. Если выражение оценивается как значение вне соответствующего диапазона [-HUGE():HUGE()]
, тогда выражение будет заменено на -Inf
или +Inf
в зависимости от ситуации. Аналогичным образом, DATA i/Z'FFFFFFFF'/
приведет к целочисленному переполнению в большинстве систем, но с -fno-range-check
значение будет "развернуто", и i
будет инициализировано вместо -1
.
источник: Сборник компиляторов GNU, руководство gfortran
Я попытался выполнить следующее, что работает нормально, но все же не на 100%
integer(kind=INT32) :: x1 = transfer(real(Z'FEDCBA09',kind=REAL32),1_INT32)
integer(kind=INT32) :: x1 = transfer(real(Z'FFFFFFFF',kind=REAL32),1_INT32)
В последнем случае с gfortran происходит сбой, так как он жалуется, что Z'FFFFFFFF'
представляет NaN.
Использование IOR(0,Z'FEDCBA09')
также не дает результатов, так как он преобразует боз-литерал с использованием INT
Вопрос: Как вы можете надежно назначить битовую комбинацию, используя константу boz-literal? То есть независимо от используемого компилятора (GNU, SUN, PGI, NAG, ...).
Ответ: Самый надежный ответ в настоящее время дает ДжимRodes in этот комментарий :
x = ior(ishft(int(Z'FEDC'),bit_size(x)/2),int(Z'BA09'))
Это будет работать на любом компиляторе и не требует другого типа данных для успешной работы.