128位的数据类

 如果有对位操作的须要,可以参考 变量操作位操作数据结构 

/*
 * 128 位数据,文件源于chromium中,但关联有多个C文件,为方便使用重新修改和定义为一个文件,
 * 128位数据类中没有除法,
 * 2022-02-26   63744457@qq.com
 *
 * */
#ifndef _LONG_LONG_INTEGER_128_BITS_H_
#define _LONG_LONG_INTEGER_128_BITS_H_

#include <stdint.h>
#include <iosfwd>
#include <ostream>

#define NET_EXPORT
#define NET_EXPORT_PRIVATE

struct __uint128_type_pod;

// An unsigned 128-bit integer type. Thread-compatible.
class __uint128_type {
public:
    __uint128_type();  // Sets to 0, but don't trust on this behavior.
    __uint128_type(uint64_t top, uint64_t bottom);
    __uint128_type(int bottom);
    __uint128_type(uint32_t bottom);  // Top 96 bits = 0
    __uint128_type(uint64_t bottom);  // hi_ = 0
    __uint128_type(const __uint128_type &val);
    __uint128_type(const __uint128_type_pod &val);

    void Initialize(uint64_t top, uint64_t bottom);

    __uint128_type& operator=(const __uint128_type& b);

    // Arithmetic operators.
    // TODO: division, etc.
    __uint128_type& operator+=(const __uint128_type& b);
    __uint128_type& operator-=(const __uint128_type& b);
    __uint128_type& operator*=(const __uint128_type& b);
    __uint128_type operator++(int);
    __uint128_type operator--(int);
    __uint128_type& operator<<=(int);
    __uint128_type& operator>>=(int);
    __uint128_type& operator&=(const __uint128_type& b);
    __uint128_type& operator|=(const __uint128_type& b);
    __uint128_type& operator^=(const __uint128_type& b);
    __uint128_type& operator++();
    __uint128_type& operator--();

    friend uint64_t Uint128Low64(const __uint128_type& v);
    friend uint64_t Uint128High64(const __uint128_type& v);

    // We add "std::" to avoid including all of port.h.
    friend NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& o,
                                                       const __uint128_type& b);

private:
    // Little-endian memory order optimizations can benefit from
    // having lo_ first, hi_ last.
    // See util/endian/endian.h and Load128/Store128 for storing a uint128.
    uint64_t lo_;
    uint64_t hi_;

    // Not implemented, just declared for catching automatic type conversions.
    __uint128_type(uint8_t);
    __uint128_type(uint16_t);
    __uint128_type(float v);
    __uint128_type(double v);
};

inline __uint128_type MakeUint128(uint64_t top, uint64_t bottom) {
    return __uint128_type(top, bottom);
}

// This is a POD form of uint128 which can be used for static variables which
// need to be operated on as uint128.
struct __uint128_type_pod {
    // Note: The ordering of fields is different than 'class uint128' but the
    // same as its 2-arg constructor.  This enables more obvious initialization
    // of static instances, which is the primary reason for this struct in the
    // first place.  This does not seem to defeat any optimizations wrt
    // operations involving this struct.
    uint64_t hi;
    uint64_t lo;
};

NET_EXPORT_PRIVATE extern const __uint128_type_pod kuint128max;

// allow uint128 to be logged
NET_EXPORT_PRIVATE extern std::ostream& operator<<(std::ostream& o,
                                                   const __uint128_type& b);

// Methods to access low and high pieces of 128-bit value.
// Defined externally from uint128 to facilitate conversion
// to native 128-bit types when compilers support them.
inline uint64_t Uint128Low64(const __uint128_type& v) {
    return v.lo_;
}
inline uint64_t Uint128High64(const __uint128_type& v) {
    return v.hi_;
}

// TODO: perhaps it would be nice to have int128, a signed 128-bit type?

// --------------------------------------------------------------------------
//                      Implementation details follow
// --------------------------------------------------------------------------
inline bool operator==(const __uint128_type& lhs, const __uint128_type& rhs) {
    return (Uint128Low64(lhs) == Uint128Low64(rhs) &&
            Uint128High64(lhs) == Uint128High64(rhs));
}
inline bool operator!=(const __uint128_type& lhs, const __uint128_type& rhs) {
    return !(lhs == rhs);
}
inline __uint128_type& __uint128_type::operator=(const __uint128_type& b) {
    lo_ = b.lo_;
    hi_ = b.hi_;
    return *this;
}

inline __uint128_type::__uint128_type(): lo_(0), hi_(0) { }
inline __uint128_type::__uint128_type(uint64_t top, uint64_t bottom)
    : lo_(bottom), hi_(top) {}
inline __uint128_type::__uint128_type(const __uint128_type &v) : lo_(v.lo_), hi_(v.hi_) { }
inline __uint128_type::__uint128_type(const __uint128_type_pod &v) : lo_(v.lo), hi_(v.hi) { }
inline __uint128_type::__uint128_type(uint64_t bottom) : lo_(bottom), hi_(0) {}
inline __uint128_type::__uint128_type(uint32_t bottom) : lo_(bottom), hi_(0) {}
inline __uint128_type::__uint128_type(int bottom) : lo_(bottom), hi_(0) {
    if (bottom < 0) {
        --hi_;
    }
}
inline void __uint128_type::Initialize(uint64_t top, uint64_t bottom) {
    hi_ = top;
    lo_ = bottom;
}

// Comparison operators.

#define CMP128(op)                                                \
    inline bool operator op(const __uint128_type& lhs, const __uint128_type& rhs) { \
    return (Uint128High64(lhs) == Uint128High64(rhs)) ?             \
    (Uint128Low64(lhs) op Uint128Low64(rhs)) :                  \
    (Uint128High64(lhs) op Uint128High64(rhs));                 \
    }

CMP128(<)
CMP128(>)
CMP128(>=)
CMP128(<=)

#undef CMP128

// Unary operators

inline __uint128_type operator-(const __uint128_type& val) {
    const uint64_t hi_flip = ~Uint128High64(val);
    const uint64_t lo_flip = ~Uint128Low64(val);
    const uint64_t lo_add = lo_flip + 1;
    if (lo_add < lo_flip) {
        return __uint128_type(hi_flip + 1, lo_add);
    }
    return __uint128_type(hi_flip, lo_add);
}

inline bool operator!(const __uint128_type& val) {
    return !Uint128High64(val) && !Uint128Low64(val);
}

// Logical operators.

inline __uint128_type operator~(const __uint128_type& val) {
    return __uint128_type(~Uint128High64(val), ~Uint128Low64(val));
}

#define LOGIC128(op)                                                 \
    inline __uint128_type operator op(const __uint128_type& lhs, const __uint128_type& rhs) { \
    return __uint128_type(Uint128High64(lhs) op Uint128High64(rhs),           \
    Uint128Low64(lhs) op Uint128Low64(rhs));            \
    }

LOGIC128(|)
LOGIC128(&)
LOGIC128(^)

#undef LOGIC128

#define LOGICASSIGN128(op)                                   \
    inline __uint128_type& __uint128_type::operator op(const __uint128_type& other) { \
    hi_ op other.hi_;                                          \
    lo_ op other.lo_;                                          \
    return *this;                                              \
    }

LOGICASSIGN128(|=)
LOGICASSIGN128(&=)
LOGICASSIGN128(^=)

#undef LOGICASSIGN128
;
// Shift operators.

inline __uint128_type operator<<(const __uint128_type& val, int amount)
{
    // uint64_t shifts of >= 64 are undefined, so we will need some
    // special-casing.
    if (amount < 64) {
        if (amount == 0) {
            return val;
        }
        uint64_t new_hi =
                (Uint128High64(val) << amount) | (Uint128Low64(val) >> (64 - amount));
        uint64_t new_lo = Uint128Low64(val) << amount;
        return __uint128_type(new_hi, new_lo);
    } else if (amount < 128) {
        return __uint128_type(Uint128Low64(val) << (amount - 64), 0);
    } else {
        return __uint128_type(0, 0);
    }
}

inline __uint128_type operator>>(const __uint128_type& val, int amount) {
    // uint64_t shifts of >= 64 are undefined, so we will need some
    // special-casing.
    if (amount < 64) {
        if (amount == 0) {
            return val;
        }
        uint64_t new_hi = Uint128High64(val) >> amount;
        uint64_t new_lo =
                (Uint128Low64(val) >> amount) | (Uint128High64(val) << (64 - amount));
        return __uint128_type(new_hi, new_lo);
    } else if (amount < 128) {
        return __uint128_type(0, Uint128High64(val) >> (amount - 64));
    } else {
        return __uint128_type(0, 0);
    }
}

inline __uint128_type& __uint128_type::operator<<=(int amount) {
    // uint64_t shifts of >= 64 are undefined, so we will need some
    // special-casing.
    if (amount < 64) {
        if (amount != 0) {
            hi_ = (hi_ << amount) | (lo_ >> (64 - amount));
            lo_ = lo_ << amount;
        }
    } else if (amount < 128) {
        hi_ = lo_ << (amount - 64);
        lo_ = 0;
    } else {
        hi_ = 0;
        lo_ = 0;
    }
    return *this;
}

inline __uint128_type& __uint128_type::operator>>=(int amount) {
    // uint64_t shifts of >= 64 are undefined, so we will need some
    // special-casing.
    if (amount < 64) {
        if (amount != 0) {
            lo_ = (lo_ >> amount) | (hi_ << (64 - amount));
            hi_ = hi_ >> amount;
        }
    } else if (amount < 128) {
        hi_ = 0;
        lo_ = hi_ >> (amount - 64);
    } else {
        hi_ = 0;
        lo_ = 0;
    }
    return *this;
}

inline __uint128_type operator+(const __uint128_type& lhs, const __uint128_type& rhs) {
    return __uint128_type(lhs) += rhs;
}

inline __uint128_type operator-(const __uint128_type& lhs, const __uint128_type& rhs) {
    return __uint128_type(lhs) -= rhs;
}

inline __uint128_type operator*(const __uint128_type& lhs, const __uint128_type& rhs) {
    return __uint128_type(lhs) *= rhs;
}

inline __uint128_type& __uint128_type::operator+=(const __uint128_type& b) {
    hi_ += b.hi_;
    uint64_t lolo = lo_ + b.lo_;
    if (lolo < lo_)
        ++hi_;
    lo_ = lolo;
    return *this;
}

inline __uint128_type& __uint128_type::operator-=(const __uint128_type& b) {
    hi_ -= b.hi_;
    if (b.lo_ > lo_)
        --hi_;
    lo_ -= b.lo_;
    return *this;
}

inline __uint128_type& __uint128_type::operator*=(const __uint128_type& b) {
    uint64_t a96 = hi_ >> 32;
    uint64_t a64 = hi_ & 0xffffffffu;
    uint64_t a32 = lo_ >> 32;
    uint64_t a00 = lo_ & 0xffffffffu;
    uint64_t b96 = b.hi_ >> 32;
    uint64_t b64 = b.hi_ & 0xffffffffu;
    uint64_t b32 = b.lo_ >> 32;
    uint64_t b00 = b.lo_ & 0xffffffffu;
    // multiply [a96 .. a00] x [b96 .. b00]
    // terms higher than c96 disappear off the high side
    // terms c96 and c64 are safe to ignore carry bit
    uint64_t c96 = a96 * b00 + a64 * b32 + a32 * b64 + a00 * b96;
    uint64_t c64 = a64 * b00 + a32 * b32 + a00 * b64;
    this->hi_ = (c96 << 32) + c64;
    this->lo_ = 0;
    // add terms after this one at a time to capture carry
    *this += __uint128_type(a32 * b00) << 32;
    *this += __uint128_type(a00 * b32) << 32;
    *this += a00 * b00;
    return *this;
}

inline __uint128_type __uint128_type::operator++(int) {
    __uint128_type tmp(*this);
    *this += 1;
    return tmp;
}

inline __uint128_type __uint128_type::operator--(int) {
    __uint128_type tmp(*this);
    *this -= 1;
    return tmp;
}

inline __uint128_type& __uint128_type::operator++() {
    *this += 1;
    return *this;
}

inline __uint128_type& __uint128_type::operator--() {
    *this -= 1;
    return *this;
}

#define  kuint128max (const __uint128_type_pod ){ \
    static_cast<uint64_t>(0xFFFFFFFFFFFFFFFFULL),\
    static_cast<uint64_t>(0xFFFFFFFFFFFFFFFFULL)\
}

inline std::ostream& operator<<(std::ostream& o, const __uint128_type& b)
{
    return (o << b.hi_ << "::" << b.lo_);
}

#endif  // NET_BASE_INT128_H_





 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值