gpt4 book ai didi

C++ 可移植浮点位表示?

转载 作者:可可西里 更新时间:2023-11-01 17:56:15 26 4
gpt4 key购买 nike

是否有符合 C++ 标准的方法来在编译时(或运行时,作为替代)确定“float”、“double”和“long double”的结构?

如果我假设 std::numeric_limits< T >::is_iec559 == truestd::numeric_limits< T >::radix == 2 ,我怀疑以下规则是可能的:

  • 第一个 X 位是有效数。
  • 接下来的 Y 位是指数。
  • 最后一位是符号位。

含糊不清的有如下表达方式:

  • size_t num_significand_bits = std::numeric_limits< T >::digits;
  • size_t num_exponent_bits = log2( 2 * std::numeric_limits< T >::max_exponent );
  • size_t num_sign_bits = 1u;

除了我知道

  • std::numeric_limits< T >::digits包括“整数位”,无论格式是否实际明确表示它,所以我不知道如何以编程方式检测和调整它。
  • 我猜 std::numeric_limits< T >::max_exponent总是 2^(num_exponent_bits)/2 .

背景:我正试图以可移植的方式克服两个问题:

  • 设置/获取有效位中的哪些位。
  • 确定“long double”的结尾位置,这样我就知道不要读取具有未初始化内存的隐式填充位。

最佳答案

简而言之,没有。如果std::numeric_limits<T>::is_iec559 , 然后你知道 T 的格式, 或多或少:你仍然需要确定字节顺序。对于其他任何事情,所有的赌注都没有了。(我知道仍在使用的其他格式甚至都没有base 2:例如,IBM 大型机使用 base 16。)IEC float 的“标准”排列有符号高阶位,然后是指数和尾数低阶位;如果你能成功地将它视为 uint64_t ,例如(通过 memcpyreinterpret_castunion —`memcpy 保证可以工作,但更少比其他两个更有效),那么:

double :

uint64_t tmp;
memcpy( &tmp, &theDouble, sizeof( double ) );
bool isNeg = (tmp & 0x8000000000000000) != 0;
int exp = (int)( (tmp & 0x7FF0000000000000) >> 52 ) - 1022 - 53;
long mant = (tmp & 0x000FFFFFFFFFFFFF) | 0x0010000000000000;

对于` float :

uint32_t tmp;
memcpy( &tmp, &theFloat, sizeof( float ) );
bool isNeg = (tmp & 0x80000000) != 0;
int exp = (int)( (tmp & 0x7F800000) >> 23 ) - 126 - 24 );
long mant = (tmp & 0x007FFFFF) | 0x00800000;

关于 long double ,更糟,因为不同编译器以不同的方式对待它,即使在同一台机器上也是如此。名义上,它是十个字节,但出于对齐的原因,它可能在事实上是 12 或 16。或者只是 double 的同义词. 如果是超过 10 个字节,我认为你可以指望它被打包进入前 10 个字节,因此 &myLongDouble给出了10 字节值的地址。但一般来说,我会避免 long double .

关于C++ 可移植浮点位表示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15301076/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com