gpt4 book ai didi

c++ - 如何在一个 64 位整数中存储和使用两个 32 位有符号整数?

转载 作者:行者123 更新时间:2023-12-01 15:07:49 25 4
gpt4 key购买 nike

首先,我想澄清一下,这个问题与问题不同:

  • How to store a 64 bit integer in two 32 bit integers and convert back again
  • Is it possible to store 2 32-bit values in one long int variable?
  • How to combine two 32-bit integers into one 64-bit integer?

  • 这个问题是存储 并使用 ,这意味着我可以做到这一点
    int64_t score = make_score(-15, 15);
    score += make_score(-5, 5); //I can use (add, subtract) the score
    int32_t a = get_a(score);
    assert(a == -20); //-15 -5 = -20
    int32_t b = get_b(score);
    assert(b == 20);//15 + 5= 20
    这对于一个 32 位 int 中的两个 16 位 int ( Stockfish did this ) 是可以实现的:
    /// Score enum stores a middlegame and an endgame value in a single integer (enum).
    /// The least significant 16 bits are used to store the middlegame value and the
    /// upper 16 bits are used to store the endgame value. We have to take care to
    /// avoid left-shifting a signed int to avoid undefined behavior.
    enum Score : int { SCORE_ZERO };

    constexpr Score make_score(int mg, int eg) {
    return Score((int)((unsigned int)eg << 16) + mg);
    }

    /// Extracting the signed lower and upper 16 bits is not so trivial because
    /// according to the standard a simple cast to short is implementation defined
    /// and so is a right shift of a signed integer.
    inline Value eg_value(Score s) {
    union { uint16_t u; int16_t s; } eg = { uint16_t(unsigned(s + 0x8000) >> 16) };
    return Value(eg.s);
    }

    inline Value mg_value(Score s) {
    union { uint16_t u; int16_t s; } mg = { uint16_t(unsigned(s)) };
    return Value(mg.s);
    }
    我正在尝试升级 mgeg来自 int16_tint32_t但是我不知道怎么做,当ScoreA + ScoreB 毁了 eg 时,我总是遇到麻烦和 mg分数里面。
    这是我尝试过但失败的方法:
    enum Score : int64_t { SCORE_ZERO };

    constexpr Score make_score(int mg, int eg) {
    return Score((int)((uint64_t)eg << 32) + mg);
    }

    inline Value eg_value(Score s) {
    union { uint32_t u; int32_t s; } eg = { uint32_t(unsigned(s + 0x80000000) >> 32) };
    return Value(eg.s);
    }

    inline Value mg_value(Score s) {
    union { uint32_t u; int32_t s; } mg = { uint32_t(unsigned(s)) };
    return Value(mg.s);
    }

    最佳答案

    使用 memcpy .
    正如原始解决方案中的评论指出的那样,这种位操作是潜在未定义行为的雷区。 memcpy允许您摆脱这些并且现代编译器很好理解,因此它仍然会产生高效的机器代码。

    enum Score : int64_t { SCORE_ZERO };

    enum Value : int32_t { FORTYTWO };

    inline Score make_score(int32_t mg, int32_t eg) {
    int64_t combined;
    std::memcpy(&combined, &eg, 4);
    std::memcpy(reinterpret_cast<char*>(&combined) + 4, &mg, 4);
    return Score(combined);
    }

    inline Value eg_value(Score s) {
    int32_t eg;
    std::memcpy(&eg, &s, 4);
    return Value(eg);
    }

    inline Value mg_value(Score s) {
    int32_t mg;
    std::memcpy(&mg, reinterpret_cast<char*>(&s) + 4, 4);
    return Value(mg);
    }
    Try it on godbolt .

    关于c++ - 如何在一个 64 位整数中存储和使用两个 32 位有符号整数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62827523/

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