【问题标题】:Hexadecimal Constants十六进制常量
【发布时间】:2018-04-21 21:09:24
【问题描述】:

我想根据其十六进制表示声明一个整数参数。有什么区别:

INTEGER(kind=int32), PARAMETER :: a = Z'FFFFFFFF'
INTEGER(kind=int32), PARAMETER :: b = int(Z'FFFFFFFF', kind=int32)
INTEGER(kind=int32), PARAMETER :: c = transfer(Z'FFFFFFFF', 1_int32)

(是的,我知道这只是-1。)

gfortran 似乎在编译过程中给了我一个整数溢出错误(有用地告诉我,我可以用-fno-range-check 忽略它)上面的ab,但不是c。

我需要使它与 Fortran 2003 兼容,因为此代码可能会使用其他地方的不同编译器进行编译。

【问题讨论】:

  • IIRC 在 Fortran 2003 和 2008 之间的规则发生了一些变化。您需要严格的 2003 吗?
  • 软件编码标准为 Fortran 2003

标签: fortran fortran2003


【解决方案1】:

第一条和第三条语句不是有效的 Fortran。 boz 文字常量只能出现在一些有限的上下文中 - int 内在是这些上下文之一。

中间的语句根据 boz-literal-constant 指定的位序列将命名常量的值设置为依赖于处理器的值。该值取决于处理器,因为结果值中的最高有效位是 1。

详细说明,使用 Fortran 2008 规则(Fortran 2003 不同,正如 Vladimir 所说):

  • boz 文字常量指定 32 个 1(或 on/.TRUE./whatever)位的序列。
  • INTEGER(INT32) 指定一个 STORAGE_SIZE 为 32 位的整数,该整数可能大于或等于该类型对象的 BIT_SIZE(由于对齐要求等原因,存储位和“值位”可能会有所不同)。
  • 如有必要,INT 内在函数会将位序列截断为相关的位大小。
    • 如果该截断序列的最左侧位为零,则 INT 内在函数的值由类似 SUM([b(i) * (i-1)**2, i = 1, SIZE(b)]) 的内容给出,其中 b 是表示位序列的数组,最右侧位在 b(1) 中.
    • 如果该截断序列的最右边位为 1,如示例中所示,则标准表示结果取决于处理器。这是为了适应在值的内部表示中使用最高有效位来表示符号的典型做法。使用非常常见的整数补码表示,您将得到 -1 的值。

在 Fortran 2003 中,位序列被解释为使用处理器上可用的最大整数表示的正数。结果值将超出 INTEGER(INT32) 对象的范围,导致代码不符合要求。

【讨论】:

  • "该值取决于处理器,因为结果值中的最高有效位为 1。" ——对不起,我不明白那句话。你能举个例子来解释一下吗?
  • 也试图理解这一点。无论原生架构如何,这种解释似乎都是大端的。但是您是说负编码可能取决于处理器?我遇到的各种文档都对假定的编码保持沉默。
  • 因此,它取决于处理器,因为它取决于处理器如何存储有符号整数。今天有没有不将有符号整数存储为二进制补码的处理器?
  • 是的(考虑您可以使用笔和纸创建符合要求的处理器),但它们可能与您无关。您打算做什么(您的问题是关于差异,而不是如何实现目标)?
  • 我正在实施Mersenne Twister。那里的一些常量以十六进制形式给出,我想直接使用它们来防止手动转换错误。我在我的桌面上进行测试,我只有gfortran,而int(Z'9D2C5680', type=int32) 给了我一个编译时错误。
猜你喜欢
  • 2021-05-04
  • 1970-01-01
  • 2017-12-20
  • 2011-07-25
  • 2012-06-10
  • 1970-01-01
  • 2018-07-26
相关资源
最近更新 更多