簡體   English   中英

C ++中的十六進制浮點文字

[英]Hexadecimal floating point literals in c++

(C++) 是否可以用十六進制浮點值初始化浮點變量?

像這樣:

'0x011.1' // 錯誤!

2016 年 2 月,佛羅里達州傑克遜維爾的 ISO C++ 標准委員會將 C++ 的技術規范P0245十六進制浮點字面量投票為 C++17。

C99語言也有這個特性,與C++特性兼容。

然而,正如Lưu Vĩnh Phúc的評論所指出的,語法0x011.1不是標准的一部分。 二進制指數對於十六進制浮點文字是強制性的。 一個原因是為了避免0x011.1F內尾隨F0x011.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

表示沒有基數分隔符的整數的十六進制數字序列。 對於十六進制浮點文字,指數從不可選: 0x1ffp100X0p-10x1.p00xf.p-10x0.123p-10xa.bp10l

十六進制浮點文字的指數語法具有以下形式
p | P exponent-sign(optional) digit-sequence

指數符號(如果存在)是 + 或 -

后綴(如果存在)是fFlL 后綴決定了浮點文字的類型:

  • (無后綴)定義雙
  • f F定義浮點數
  • l L定義 long double

另請參閱 GitHub 上的當前工作草案 C++17,第 2.13.4浮動文字https : //github.com/cplusplus/draft/raw/master/papers/n4604.pdf

浮動字面量:
十進制浮點文字
十六進制浮動文字
十進制浮點文字:
小數常數指數部分opt浮動后綴opt
數字序列指數-部分浮點后綴選擇
十六進制浮動文字:
十六進制的前綴十六進制分數不變二進制指數部分浮點后綴選擇
十六進制前綴的十六進制數字序列二進制指數部分浮點后綴選擇
分數常數:
數字序列選擇 數字序列
數字序列。
十六進制小數常數:
十六進制數字序列選擇 十六進制數字序列
十六進制數字序列。
指數部分:
e符號選擇數字序列
E符號選擇數字序列
二進制指數部分:
p符號選擇數字序列
P符號選擇數字序列
標志:其中之一
+ -
數字序列:
數字
數字序列'選擇數字
浮動后綴:之一
f l F L

1浮點文字由指定基數的可選前綴、整數部分、小數點、小數部分、 eEpP 、可選的帶符號整數指數和可選的類型后綴組成。 如果沒有前綴,整數和小數部分都由十進制(基數為 10)數字序列組成,如果前綴為0x0X則由十六進制(基數為 16)數字組成。 在前一種情況下,文字是十進制浮動文字,在后一種情況下是十六進制浮動文字 在確定其值時,將忽略數字序列十六進制數字序列中的可選分隔單引號。 [示例:文字1.602'176'565e-191.602176565e-19具有相同的值。 結束示例] 整數部分或小數部分(不是兩者)都可以省略。 可以從十進制浮點文字中省略小數點或字母 e 或 E 和指數(不是兩者)。 可以從十六進制浮點文字中省略小數點(但不是指數)。 的整數部分,任選的小數點,和可選的小數部分,形成浮字面的有效數 在十進制浮點文字中,指數(如果存在)表示要縮放有效數的 10 的冪。 在十六進制浮點文字中,指數表示要縮放有效數的 2 的冪。 [示例:文字49.6250xC.68p+2具有相同的值。 結束示例] 如果縮放值在其類型的可表示值范圍內,則結果是縮放值(如果可表示),否則以實現定義的方式選擇最接近縮放值的較大或較小的可表示值。 除非后綴明確指定,否則浮動文字的類型是double 后綴fF指定float ,后綴lL指定long double 如果縮放值不在其類型的可表示值范圍內,則程序格式錯誤。

正如unwind所建議的,您可以使用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 支持十六進制浮點文字。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM