从FloatingLiteral/AFPloat获取原始解析的数字

Get the original parsed number from FloatingLiteral/APFloat

本文关键字:数字 原始 获取 FloatingLiteral AFPloat      更新时间:2023-10-16

我开始使用clang作为我目前正在开发的有界模型检查器的前端,我需要一些从AST获得的浮点数的帮助。

例如,对于这个程序:

int main()
{
  float a = 1.0f;
  long double b = 5567.765434376l;
}

生成的AST为:

FunctionDecl 0x1dea160 </home/mramalho/main.c:3:1, line:7:1> line:3:5 main 'int ()'
`-CompoundStmt 0x1dea368 <line:4:1, line:7:1>
  |-DeclStmt 0x1dea298 <line:5:3, col:17>
  | `-VarDecl 0x1dea218 <col:3, col:13> col:9 a 'float' cinit
  |   `-FloatingLiteral 0x1dea278 <col:13> 'float' 1.000000e+00
  `-DeclStmt 0x1dea350 <line:6:3, col:34>
    `-VarDecl 0x1dea2c0 <col:3, col:19> col:15 b 'long double' cinit
      `-FloatingLiteral 0x1dea320 <col:19> 'long double' 5.567765e+03

我从.getValue()中得到的APFLoat数字没有多大帮助,因为它被存储为已经转换的数字。

特别是,我想知道是否可以获得原始数字(在上面的例子中,1.0f和5567.765434376l)。如果可能的话,在适用的情况下使用(+/-)Inf和/或NaN的字符串会很好,但不是必需的。

我尝试了几种方法,但最终总是得到原始数字的修剪版本。

我最好的选择是方法convertFromString和结构DecimalInfo(都在APFloat上),但我找不到方法来访问它们,因为在我获得FloatingLiteral时,数字已经创建好了。

谢谢。

不知道是否可以回答自己的问题,但以下是我解决问题的方法:

llvm::SmallVector<char, 32> string;
val.toString(string, 32, 0);

其中val是APFloat。来自文件:

/// Converts this value into a decimal string.
///
/// param FormatPrecision The maximum number of digits of
///   precision to output.  If there are fewer digits available,
///   zero padding will not be used unless the value is
///   integral and small enough to be expressed in
///   FormatPrecision digits.  0 means to use the natural
///   precision of the number.
/// param FormatMaxPadding The maximum number of zeros to
///   consider inserting before falling back to scientific
///   notation.  0 means to always use scientific notation.
///
/// Number       Precision    MaxPadding      Result
/// ------       ---------    ----------      ------
/// 1.01E+4              5             2       10100
/// 1.01E+4              4             2       1.01E+4
/// 1.01E+4              5             1       1.01E+4
/// 1.01E-2              5             2       0.0101
/// 1.01E-2              4             2       0.0101
/// 1.01E-2              4             1       1.01E-2

然后它是一个简单的迭代来获得值。

它还为无穷大的值提供"Inf"字符串。