c ++中的十六进制浮点文字

Vis*_*iva 4 c++ floating-point hex

(C++)是否可以使用十六进制浮点值初始化浮点变量?

像这样的事情:

'0x011.1'//错了!

oli*_*bre 12

技术规范P0245 C++的十六进制浮点文字已于2016年2月在佛罗里达州杰克逊维尔的ISO C++标准委员会中投票选入C++ 17.

C99语言也具有此功能,并且C++功能兼容.

然而,正如LưuVĩnhPhúc的评论所指出的那样,语法0x011.1不是标准的一部分.二进制指数对于十六进制浮点文字是必需的.一个原因是避免F内部尾随的模糊性0x011.1F.它是F小数部分的十六进制数字还是浮动后缀的含义float
因此追加p后跟正十进制数,例如:0x011.1p0.

请参阅cppreference.com上更易阅读的浮动文字页面.

0x | 0X hex-digit-sequence
0x | 0X hex-digit-sequence .
0x | 0X hex-digit-sequence(optional) . hex-digit-sequence

十六进制数字序列,表示没有基数分隔符的整数.该指数是从来没有可选的十六进制浮点文字:0x1ffp10,0X0p-1,0x1.p0,0xf.p-1,0x0.123p-1,0xa.bp10l

十六进制浮点文字的指数语法具有该形式
p | P exponent-sign(optional) digit-sequence

指数符号(如果存在)是+或 -

后缀,如果存在,是一个f,F,l,或L.后缀确定浮点文字的类型:

  • (无后缀)定义double
  • f F 定义浮点数
  • l L 定义long double

另请参阅当前工作草案C++ 17,第2.13.4章GitHub上的浮动文字:https://github.com/cplusplus/draft/raw/master/papers/n4604.pdf

floating-literal:
decimal-floating-literal
hexadecimal-floating-literal
decimal-floating-literal:
fractional-constant exponent-part opt floating-suffix opt
digit-sequence exponent-part floating-suffix opt
hexadecimal-floating-literal:
hexadecimal-prefix hexadecimal-fractional-constant binary-exponent-part floating-suffix opt
十六进制前缀十六进制数字序列binary-exponent-part浮动后缀opt
fractional-constant:
digit-sequence opt.数字序列
数字序列.
十六进制分数不变:
十六进制数字序列选择.十六进制数字序列
十六进制数字序列.
指数部分:
e 签署选择数位序列
E 符号选择数位序列
二进制指数部分:
p 符号选择数位序列
P 符号选择数位序列
符号:一个
+ -
位序列:

位序列" 选择
浮点后缀:一个的
f l F L

1一个浮动文字由一个可选的前缀指定的基础上,的整数部分,一个小数点,一个小数部分,一个的e,E,pP,任选符号整数指数,和一个可选的类型后缀.如果没有前缀,则整数和小数部分都包含十进制(十进制)数字序列,如果前缀为0x或,则为十六进制(十六进制)数字0X.该文本是一个十进制浮点字面在前者的情况下和一个十六进制浮点文字在后一种情况.在确定其值时,将忽略数字序列十六进制数字序列中的可选分隔单引号.[ 示例:文字1.602’176’565e-191.602176565e-19具有相同的值.- 结束示例 ]可以省略整数部分或小数部分(不是两者).小数浮动字面可以省略小数点或字母e或E和指数(不是两者).可以从十六进制浮点文字中省略小数点(但不是指数).的整数部分,任选的小数点,和任选的级分的一部分,形成所述有效数浮动字面的.在十进制浮点字面值中,指数(如果存在)指示有效数字缩放的10的幂.在十六进制浮点字面值中,指数表示有效位缩放的2的幂.[ 示例:文字49.6250xC.68p+2具有相同的值.- 结束示例 ]如果缩放值在其类型的可表示值的范围内,则结果是可表示的缩放值,否则最接近缩放值的较大或较小可表示值,以实现定义的方式选择.double除非后缀明确指定,否则浮动文字的类型除外.后缀fF指定float,后缀lL指定long double.如果缩放值不在其类型的可表示值范围内,则程序格式不正确.

正如放松建议,你可以使用strtof().以下代码段解码十六进制浮动文字(没有C++ 17):

#include <iostream>
#include <cstdlib>
#include <cstdio>

int main(int argc, char *argv[])
{
  if (argc != 2)
  {
    std::cout <<"Usage: "<< argv[0] <<" 0xA.Bp-1  => Decode hexfloat" "\n";
    return 1;
  }

  long double l;
  double      d;
  float       f;

  std::cout <<"Decode floating point hexadecimal = "<< argv[1];
  //std::istringstream(argv[1]) >> std::hexfloat >> d;
  l = std::strtold(argv[1],NULL); if(errno == ERANGE) std::cout << "\n" "std::strtold() range error";
  d = std::strtod (argv[1],NULL); if(errno == ERANGE) std::cout << "\n" "std::strtod() range error";
  f = std::strtof (argv[1],NULL); if(errno == ERANGE) std::cout << "\n" "std::strtod() range error";

  std::cout <<"\n"  "long double = "<< std::defaultfloat << l <<'\t'<< std::hexfloat << l
            <<"\n"  "double      = "<< std::defaultfloat << d <<'\t'<< std::hexfloat << d
            <<"\n"  "float       = "<< std::defaultfloat << f <<'\t'<< std::hexfloat << f <<'\n';
}
Run Code Online (Sandbox Code Playgroud)


unw*_*ind 1

不,C++ 不支持文字,它不是标准的一部分。

一个不可移植的解决方案是使用一个编译器将其添加为扩展(GCC 就是这样做的)。

strtof()一种可移植的解决方法是在运行时使用 eg或strtod()for从字符串文字中解析它们double

正如评论中指出的,您还可以选择将常量存储在 C 文件中。不过,这样做需要您能够访问 C99 编译器,因为十六进制浮点文字是 C99 级别的功能。由于使用新的 C++ 编译器但没有 C99 编译器(即:Visual Studio)的环境非常常见,因此这可能不是一个可行的解决方案。

更新: C++17 支持十六进制浮点文字。

  • 如果要使用运行时解决方案,不妨使用所需的十六进制浮点在 C 中简单地定义外部浮点对象,然后将它们链接起来。这至少运行时成本非常低,与“strtof”不同(它产生“float”,但OP可能需要“double”)。除了使用支持十六进制浮点的 C++ 编译器或使用自定义预处理器将十六进制浮点转换为十进制(以及使用将十进制数字准确转换为浮点的 C++ 编译器)之外,这将生成可能的最佳代码。 (2认同)
  • 当然,C++11有用户定义的文字。他们支持任何你希望他们支持的东西。六角浮子很容易。 (2认同)
  • C++17 将支持十六进制浮点数。 (2认同)