创建包含字符序列的nan时,如何获取字符序列?

时间:2018-08-16 07:41:47

标签: c++ floating-point ieee-754

这样做的时候

const double d = std::nan ("Hello");

您将获得一个包含字符串“ Hello”的NAN。如何从变量d中退回该字符串?根本没有标准的符合方式吗?如果无法取回字符串,此功能似乎毫无意义。

2 个答案:

答案 0 :(得分:3)

C ++标准表示,在为fprintf,其亲戚(例如printf)格式化并由{{1}继承的C ++功能格式化格式时,实现可能会显示NaN编码的数据。 },例如输出流格式化程序。这是C ++标准中唯一的明确条款,用于获取有关NaN中数据的信息。 (我在C标准中包含了语句,C ++通过引用将其合并。)关于此,该标准表示,实现可能在格式化NaN时会包含编码数据,但是它位于一种实现定义的方式,实现可以省略。

当然,您可以通过检查代表NaN的字节来检查以NaN编码的数据。但是,如何定义传递给fprintf函数的字符是实现定义的。一个实现可以选择不对其进行任何操作,可以将它们按字面意义包含在NaN的字节中(如果适合),或者可以对其进行编码或解释,例如期望字符串中的十六进制数字将被编码为NaN的位。 nan常用的IEEE-754基本64位二进制浮点格式有51位可用于安静的NaN的有效载荷,足以固定六个8位字符,因此字符串“ Hello” 可以以NaN编码。

以下是标准对double函数的描述:

  • C ++从C继承nan函数,并将其留给C来指定其功能。
  • C说nan等同于nan("n-char-sequence")
  • C表示 n-char-sequence 是由 digit nondigit 个字符组成的序列。 数字字符是0-9,非数字字符是_,A-Z和a-z。因此字符串strtod("NAN(n-char-sequence)", (char**)NULL) n-char-sequence
  • C说,大约"Hello"中带有* n-char-equence的“ NAN”, n-char-sequence 的含义是实现定义的。

因此,实现可以对您在strtod参数中提供的字节进行编码。

C标准(以及继承的C ++)对格式化NaN的描述是:

  • “表示为nan的双参数将转换为[-] nan或[-] nan( n-char-sequence )样式之一,任何n字符序列的含义都是实现定义的。”

答案 1 :(得分:0)

这完全是对std::nan的误解。 参见documentation

  

调用std :: nan(“ n-char-sequence”),其中n-char-sequence是一个   数字,拉丁字母和下划线的顺序等效于   调用std :: strtod(“ NAN(n-char-sequence)”,(char **)nullptr);。

基本上,“ Not a Number”可以用几个不同的安静NAN表示-无效浮点的表示。 std::nan提供了一种生成此安静NAN的方法。之所以需要它,是因为常规C ++文字不提供这种功能。
因此,它不会“包装”任何类型的字符串,只要字符串应表示一个数字,否则您将收到NAN的常规表示形式。使用“ hello”是没有意义的,并且无法从您的d中重新获得/重新创建字符串值。

如果要报告错误的更多详细信息,应使用C ++异常。例如std::invalid_argument
我没有自定义完全NAN可能有用的示例,也许其他人也可以。