Skip to content

Commit

Permalink
Update uint128_t the hard way to 00714e6
Browse files Browse the repository at this point in the history
  • Loading branch information
hoffmang9 committed Mar 4, 2021
1 parent 6a8176d commit 959c865
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 73 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-aarch64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
source venv/bin/activate
python -m pip install --upgrade pip
pip install wheel
pip install cibuildwheel==1.9.0
pip install cibuildwheel==1.10.0
- name: Lint source with flake8
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
python -m build --sdist --outdir dist .
- name: Build ${{ matrix.os }} wheels and test
uses: joerick/cibuildwheel@v1.9.0
uses: joerick/cibuildwheel@v1.10.0
with:
output-dir: dist
env:
Expand Down
118 changes: 63 additions & 55 deletions uint128_t/uint128_t.cpp
Original file line number Diff line number Diff line change
@@ -1,25 +1,9 @@
#include "uint128_t.build"
#include <cstring>

const uint128_t uint128_0(0);
const uint128_t uint128_1(1);

uint128_t::uint128_t()
: UPPER(0), LOWER(0)
{}

uint128_t::uint128_t(const uint128_t & rhs)
: UPPER(rhs.UPPER), LOWER(rhs.LOWER)
{}

uint128_t::uint128_t(uint128_t && rhs)
: UPPER(std::move(rhs.UPPER)), LOWER(std::move(rhs.LOWER))
{
if (this != &rhs){
rhs.UPPER = 0;
rhs.LOWER = 0;
}
}

uint128_t::uint128_t(std::string & s) {
init(s.c_str());
}
Expand All @@ -29,56 +13,80 @@ uint128_t::uint128_t(const char *s) {
}

void uint128_t::init(const char *s) {
if (s == NULL || s[0] == 0) { uint128_t(); return; }
if (s[1] == 'x')
s += 2;
else if (*s == 'x')
s++;
if (s == NULL || s[0] == 0){
LOWER = UPPER = 0;
return;
}

UPPER = ConvertToUint64(s);
LOWER = ConvertToUint64(s + 16);
}
while (*s == ' ') ++s;

uint64_t uint128_t::ConvertToUint64(const char *s) const {
int count = 0;
uint64_t val = 0;
uint8_t hv = HexToInt(s++);
while (hv != 0xFF && count < 16) {
val = (val << 4) | hv;
hv = HexToInt(&s[count]);
count++;
if (std::memcmp(s, "0x", 2) == 0){
_init_hex(&s[2]);
}
else if (std::memcmp(s, "0o", 2) == 0){
_init_oct(&s[2]);
}
else{
_init_dec(s);
}
return val;
}

uint8_t uint128_t::HexToInt(const char *s) const {
uint8_t ret = 0xFF;
if (*s >= '0' && *s <= '9') {
ret = uint8_t(*s - '0');
}
else if (*s >= 'a' && *s <= 'f') {
ret = uint8_t(*s - 'a' + 10);
void uint128_t::_init_hex(const char *s) {
// 2**128 = 0x100000000000000000000000000000000.
LOWER = UPPER = 0;
int i;
for (i = 0; *s && i < 16; ++s, ++i){
if ('0' <= *s && *s <= '9'){
LOWER *= 16;
LOWER += *s - '0';
}
else if ('A' <= *s && *s <= 'F'){
LOWER *= 16;
LOWER += *s + (10 - 'A');
}
else if ('a' <= *s && *s <= 'f'){
LOWER *= 16;
LOWER += *s + (10 - 'a');
}
else{
return;
}
}
else if (*s >= 'A' && *s <= 'F') {
ret = uint8_t(*s - 'A' + 10);
for (; *s && i < 32; ++s, ++i){
if ('0' <= *s && *s <= '9'){
*this *= 16;
*this += *s - '0';
}
else if ('A' <= *s && *s <= 'F'){
*this *= 16;
*this += *s + (10 - 'A');
}
else if ('a' <= *s && *s <= 'f'){
*this *= 16;
*this += *s + (10 - 'a');
}
else{
return;
}
}
return ret;
}

uint128_t & uint128_t::operator=(const uint128_t & rhs){
UPPER = rhs.UPPER;
LOWER = rhs.LOWER;
return *this;
void uint128_t::_init_dec(const char *s){
// 2**128 = 340282366920938463463374607431768211456.
LOWER = UPPER = 0;
for (int i = 0; '0' <= *s && *s <= '9' && i < 39; ++s, ++i){
*this *= 10;
*this += *s - '0';
}
}

uint128_t & uint128_t::operator=(uint128_t && rhs){
if (this != &rhs){
UPPER = std::move(rhs.UPPER);
LOWER = std::move(rhs.LOWER);
rhs.UPPER = 0;
rhs.LOWER = 0;
void uint128_t::_init_oct(const char *s){
// 2**128 = 0o4000000000000000000000000000000000000000000.
LOWER = UPPER = 0;
for (int i = 0; '0' <= *s && *s <= '7' && i < 43; ++s, ++i){
*this *= 8;
*this += *s - '0';
}
return *this;
}

uint128_t::operator bool() const{
Expand Down
47 changes: 36 additions & 11 deletions uint128_t/uint128_t.include
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ THE SOFTWARE.

With much help from Auston Sterling

Thanks to Stefan Deigm�ller for finding
Thanks to Stefan Deigmüller for finding
a bug in operator*.

Thanks to Fran�ois Dessenne for convincing me
Thanks to François Dessenne for convincing me
to do a general rewrite of this class.
*/

Expand All @@ -42,6 +42,8 @@ to do a general rewrite of this class.
#include <utility>
#include <vector>

#include "endianness.h"

class UINT128_T_EXTERN uint128_t;

// Give uint128_t type traits
Expand All @@ -53,19 +55,29 @@ namespace std { // This is probably not a good idea

class uint128_t{
private:
#ifdef __BIG_ENDIAN__
uint64_t UPPER, LOWER;
#endif
#ifdef __LITTLE_ENDIAN__
uint64_t LOWER, UPPER;
#endif

public:
// Constructors
uint128_t();
uint128_t(const uint128_t & rhs);
uint128_t(uint128_t && rhs);
uint128_t() = default;
uint128_t(const uint128_t & rhs) = default;
uint128_t(uint128_t && rhs) = default;
uint128_t(std::string & s);
uint128_t(const char *s);

template <typename T, typename = typename std::enable_if<std::is_integral<T>::value, T>::type >
uint128_t(const T & rhs)
#ifdef __BIG_ENDIAN__
: UPPER(0), LOWER(rhs)
#endif
#ifdef __LITTLE_ENDIAN__
: LOWER(rhs), UPPER(0)
#endif
{
if (std::is_signed<T>::value) {
if (rhs < 0) {
Expand All @@ -76,18 +88,30 @@ class uint128_t{

template <typename S, typename T, typename = typename std::enable_if <std::is_integral<S>::value && std::is_integral<T>::value, void>::type>
uint128_t(const S & upper_rhs, const T & lower_rhs)
#ifdef __BIG_ENDIAN__
: UPPER(upper_rhs), LOWER(lower_rhs)
#endif
#ifdef __LITTLE_ENDIAN__
: LOWER(lower_rhs), UPPER(upper_rhs)
#endif
{}

// RHS input args only

// Assignment Operator
uint128_t & operator=(const uint128_t & rhs);
uint128_t & operator=(uint128_t && rhs);
uint128_t & operator=(const uint128_t & rhs) = default;
uint128_t & operator=(uint128_t && rhs) = default;

template <typename T, typename = typename std::enable_if<std::is_integral<T>::value, T>::type >
uint128_t & operator=(const T & rhs){
UPPER = 0;

if (std::is_signed<T>::value) {
if (rhs < 0) {
UPPER = -1;
}
}

LOWER = rhs;
return *this;
}
Expand Down Expand Up @@ -187,12 +211,12 @@ class uint128_t{
bool operator||(const uint128_t & rhs) const;

template <typename T, typename = typename std::enable_if<std::is_integral<T>::value, T>::type >
bool operator&&(const T & rhs){
bool operator&&(const T & rhs) const{
return static_cast <bool> (*this && rhs);
}

template <typename T, typename = typename std::enable_if<std::is_integral<T>::value, T>::type >
bool operator||(const T & rhs){
bool operator||(const T & rhs) const{
return static_cast <bool> (*this || rhs);
}

Expand Down Expand Up @@ -286,8 +310,9 @@ class uint128_t{
std::pair <uint128_t, uint128_t> divmod(const uint128_t & lhs, const uint128_t & rhs) const;
void init(const char * s);
void ConvertToVector(std::vector<uint8_t> & current, const uint64_t & val) const;
uint8_t HexToInt(const char *s) const;
uint64_t ConvertToUint64(const char *s) const;
void _init_hex(const char *s);
void _init_dec(const char *s);
void _init_oct(const char *s);

public:
uint128_t operator/(const uint128_t & rhs) const;
Expand Down
10 changes: 5 additions & 5 deletions uint128_t/uint128_t_config.include
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#ifndef _UINT128_T_CONFIG_
#define _UINT128_T_CONFIG_
#if defined(_MSC_VER)
// #if defined(_DLL)
// #define _UINT128_T_EXPORT __declspec(dllexport)
// #define _UINT128_T_IMPORT __declspec(dllimport)
// #else
#if defined(_DLL)
#define _UINT128_T_EXPORT __declspec(dllexport)
#define _UINT128_T_IMPORT __declspec(dllimport)
#else
#define _UINT128_T_EXPORT
#define _UINT128_T_IMPORT
// #endif
#endif
#else
// All modules on Unix are compiled with -fvisibility=hidden
// All API symbols get visibility default
Expand Down

0 comments on commit 959c865

Please sign in to comment.