十六进制浮点文字
Hexadecimal floating point literals
是否可以用C++中的十六进制浮点值初始化浮点变量?
类似这样的东西:
double d = 0x011.1; // wrong!
2016年2月,在佛罗里达州杰克逊维尔举行的ISO C++标准委员会上,C++的十六进制浮点文字技术规范P0245已被投票通过C++17。
C99语言也有这个特性,并且C++特性是兼容的。
然而,正如Lưu Vĩnh Phúc的评论所指出的,语法0x011.1
不是标准的一部分。二进制指数对于十六进制浮点文字是必需的。一个原因是为了避免CCD_ 3内的尾随CCD_。是小数部分的十六进制数字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
、F
0或L
之一。后缀决定浮点文字的类型:
- (无后缀)定义双
f F
定义浮点l L
定义长双
另请参阅当前的工作草案C++17,章节§2.13.4 GitHub上的浮动文本:https://github.com/cplusplus/draft/raw/master/papers/n4604.pdf
浮动文字:
/emsp十进制浮动文字
/emsp十六进制浮点文字
十进制浮点文字:
/emsp分数常数指数部分opt浮动后缀option
/emsp数字序列指数部分浮动后缀opt
十六进制浮动文字:
/emsp十六进制前缀十六进制分数常量二进制指数部分浮动后缀opt
/emsp十六进制前缀十六进制数字序列二进制指数部分浮动后缀opt
分数常数:
/emsp数字序列opt。数字序列
/emsp数字序列
十六进制分数常数:
/emsp十六进制数字序列opt。十六进制数字序列
/emsp十六进制数字序列
指数部分:符号opt数字序列
/emsp;E
符号opt数字序列
二进制指数部分:
/emsp;p
符号opt数字序列
/emsp;P
符号opt数字序列
标记:
/emsp;+
-
数字序列:
/emsp数字
/emsp数字序列'opt数字
浮动后缀:
/emsp;0x011.1F
0l
F
L
1浮动文字由指定基数、整数部分、基点、小数部分、
e
、E
、p
或P
的可选前缀、可选带符号整数指数和可选类型后缀组成。如果没有前缀,整数和小数部分都由十进制(以十为基数)数字组成,如果前缀是0x
或0X
,则由十六进制(以十六为基数)的数字组成。在前一种情况下,文本是十进制浮动文本,在后一种情况中,文本是十六进制浮动文本。可选以数字序列或十六进制分隔单引号-数字序列在确定其值时被忽略。[示例:文字1.602’176’565e-19
和1.602176565e-19
具有相同的值。--结束示例]可以省略整数部分或小数部分(不能同时省略)。小数点或字母e或e和指数(不能同时省略)都可以从十进制浮点文字中省略。可以从十六进制浮点文字中省略基数点(而不是指数)。整数部分、可选的基数点和可选的小数部分构成浮动文字的有效位。在十进制浮动文字中,指数(如果存在)表示有效位要缩放的10的幂。在十六进制浮动文字中,指数表示有效位要缩放的2的幂。[示例:文字49.625
和0xC.68p+2
具有相同的值。--结束示例]如果缩放值在其类型的可表示值范围内,则结果为缩放值(如果可表示),否则为最接近缩放值的较大或较小可表示值(以实现定义的方式选择)。除非由后缀明确指定,否则浮动文字的类型为double
。后缀f
和F
指定float
,后缀l
和L
指定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';
}
不,C++不支持文字,它不是标准的一部分。
一个不可移植的解决方案是使用一个编译器将其添加为扩展(GCC会这样做)。
一种可移植的解决方法是在运行时使用例如strtof()
或strtod()
来解析double
的字符串文本。
正如注释中所指出的,您也可以选择将常量存储在C文件中。但是,这样做需要您能够访问C99编译器,因为十六进制浮点文字是C99级别的特性。由于带有新C++编译器但没有C99编译器(读作:Visual Studio)的环境非常常见,因此这可能不是一个可行的解决方案。
更新:C++17支持十六进制浮点文字。
- 如何在openssl-ecc中获取十六进制格式的私钥
- 如何将包含epoch时间的十六进制字符串转换为time_t
- 将字符指针十六进制转换为字符串并保存在文本文件C++中
- 如何将一个ostringstream十六进制字符串字符对转换为单个unit8t等价的二进制值
- 如何在C++中用std::cout正确显示带十六进制的字符串文本
- 通过错误处理,在C++中可靠地获得用户十六进制输入
- 为什么mpfr_printf与十六进制浮点(%a转换说明符)的printf不同
- 在 std::无符号字符的向量处存储 int 的十六进制表示形式
- 指向存储在字符串 c++ 中的十六进制
- 读取文件中所有可能的十六进制 16 字节序列并打印每个序列
- C ++如何使用UTF8十六进制代码打印UTF8符号?
- C++17 十六进制浮点文字单精度后缀冲突?
- fprintf:打印文字十六进制字符串
- 如何使用C预处理器生成可变大小(取决于操作系统)的十六进制文字
- 十六进制浮点文字
- 为什么此输出看起来不确定?(是十六进制文字的冲刺、printf 还是语法?
- 如何将二进制十六进制文字输入 std::istream
- 十六进制文字的wsign -conversion警告
- 在C++中,用十六进制或八进制表示的整型文字的默认类型是什么
- 是有符号的十六进制文字