如何在C++中获取long double的有效位长?

vulvrdjw  于 2022-12-27  发布在  其他
关注(0)|答案(2)|浏览(231)

通过std::numeric_limits可以得到long double、最小值等各种信息,通过sizeof(long double)可以得到内存的使用情况。
但是long double的有效字节/位数在C++标准中没有规定,它可能是80/96/128或其他,那么是否有一种编译时方法来获得有效位长度?
便携式方法更好。

void dump(auto x)
{
    auto vss = bit_cast<bitset<sizeof(x) * 8>>(x);
    cout << vss.to_string().substr(0, 48) << ' ' << vss.to_string().substr(48) << endl;
}

int main(int argc, char const *argv[])
{

    long double x = 0;

    dump(x);
    dump(-x);

    return 0;
}

在x86-64上,你会看到只有第79位被翻转了,所以128位中只有80位是有效的。

yhxst69z

yhxst69z1#

#include <bit>
#include <cstddef>

constinit size_t valid_bits = []
{
    long double zero{};

    struct long_double_bytes
    {
        unsigned char b[sizeof(long double)];
    };

    long_double_bytes x = std::bit_cast<long_double_bytes>(zero);
    long_double_bytes y = std::bit_cast<long_double_bytes>(-zero);

    for (size_t i = 0; i < sizeof(long double); i++)
    {
        x.b[i] ^= y.b[i];
    }

    size_t r = 0, i;
    for (i = 0; i < sizeof(long double) && !x.b[i]; i++)
    {
        r += 8;
    }
    for (size_t j = 0; j < 8 && !((x.b[i] >> j) & 1); j++)
    {
        r++;
    }

    return r + 1;
}();

编译时解决方案。

ippsafx7

ippsafx72#

仅仅数零件还不够吗?
沿着这条线

#include <iostream>
#include <cfloat>

static unsigned int ilog2(unsigned int val) {
    if (val == 0) return UINT_MAX;
    if (val == 1) return 0;
    unsigned int ret = 0;
    while (val > 1) {
        val >>= 1;
        ret++;
    }
    return ret;
}

int main() {
    unsigned int bitsinLDBL = LDBL_MANT_DIG; // mantissa
    bitsinLDBL += ilog2(LDBL_MAX_EXP);       // exponent
    bitsinLDBL += 1u;                        // sign bit

    std::cout << bitsinLDBL << " " << bitsinLDBL/CHAR_BIT << '\n';
    return 0;
}

相关问题