GithubHelp home page GithubHelp logo

calccrypto / uint128_t Goto Github PK

View Code? Open in Web Editor NEW
215.0 13.0 46.0 2 MB

C++ unsigned 128 bit integer type

License: MIT License

C++ 95.23% Makefile 2.28% C 2.04% Shell 0.45%
c-plus-plus unsigned-integers

uint128_t's Introduction

uint128_t

An unsigned 128 bit integer type for C++

Copyright (c) 2013 - 2018 Jason Lee @ calccrypto at gmail.com

Please see LICENSE file for license.

uint128_t

Acknowledgements

With much help from Auston Sterling

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

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

Thanks to John Skaller for making symbols visible when compiling as a shared library. This was originally done in uint256_t, which I copied into here.

Usage

This is simple implementation of an unsigned 128 bit integer type in C++. It's meant to be used like a standard uintX_t, except with a larger bit size than those provided by C/C++.

In Code

All that needs to be done in code is #include "uint128_t.h"

#include <iostream>
#include "uint128_t.h"

int main() {
    uint128_t a = 1;
    uint128_t b = 2;
    std::cout << (a | b) << std::endl;
    return 0;
}

Compilation

A C++ compiler supporting at least C++11 is required.

Compilation can be done by directly including uint128_t.cpp in your compile command, e.g. g++ -std=c++11 main.cpp uint128_t.cpp, or other ways, such as linking the uint128_t.o file, or creating a library, and linking the library in.

uint128_t's People

Contributors

calccrypto avatar dlaugt avatar gabrielravier avatar graydon avatar jamessmartcell avatar katahiromz avatar kotbenek avatar ntrifunovic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

uint128_t's Issues

[bug] Wrong implementation of operator+= with negative numbers

When the operator+= is used with a signed integer it returns a wrong result when a negative amount is added as follows:

// g++ test.cpp uint128_t/uint128_t.cpp -g -o test -std=c++11
#include <iostream>
#include "uint128_t/uint128_t.h"

int main(int argc, char *argv[])
{
	int i = -1;
	uint128_t u128 = 10;
	uint64_t u64 = 10;
	
	u128 += i;
	u64 += i;
	std::cout << "u128=" << u128.str() << " u64=" << u64 << " TEST RESULT=" << (u128 == u64 ? "OK" : "FAIL") << std::endl;
	
	u128 = 10;
	u64 = 10;
	i = 1;
	u128 += i;
	u64 += i;
	std::cout << "u128=" << u128.str() << " u64=" << u64 << " TEST RESULT=" << (u128 == u64 ?  "OK" : "FAIL") << std::endl;
	
	return 0;
}

output:

u128=18446744073709551625 u64=9 TEST RESULT=FAIL
u128=11 u64=11 TEST RESULT=OK

It returns 18446744073709551625 instead of 9.

How to allocate U128 to two U64?

Hi Author,

Thank you for your contribution!i am trying to use your code to implement arithmetic for bigint,but i found the testcase abou it is too easy , i want to know how do you allocate U128 to two U64 ? break down U128 into two binary number ? or other way.

Thanks!

double/float conversion/operations

code.c++:95:17: error: no viable overloaded '='
    monthsTotal = static_cast<uint64_t>(daysTotal)/30.417;
    ~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./uint128_t/uint128_t.include:85:21: note: candidate function not viable: no known
      conversion from 'double' to 'const uint128_t' for 1st argument
        uint128_t & operator=(const uint128_t & rhs);
                    ^
./uint128_t/uint128_t.include:86:21: note: candidate function not viable: no known
      conversion from 'double' to 'uint128_t' for 1st argument
        uint128_t & operator=(uint128_t && rhs);
                    ^
./uint128_t/uint128_t.include:89:21: note: candidate template ignored: requirement
      'std::is_integral<double>::value' was not satisfied [with T = double]
        uint128_t & operator=(const T & rhs){
                    ^
1 warning and 1 error generated.

code.c++:99:28: error: use of overloaded operator '/' is ambiguous (with operand
      types 'AudioTime_Format' (aka 'uint128_t') and 'float')
    monthsTotal = daysTotal/static_cast<float>(30.417);
                  ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
code.c++:99:28: note: because of ambiguity in conversion of 'AudioTime_Format'
      (aka 'uint128_t') to 'float'
./uint128_t/uint128_t.include:96:9: note: candidate function
        operator bool() const;
        ^
./uint128_t/uint128_t.include:97:9: note: candidate function
        operator uint8_t() const;
        ^
./uint128_t/uint128_t.include:98:9: note: candidate function
        operator uint16_t() const;
        ^
...

This doesn't work

#include
#include "uint256_t.h"

int main() {
uint256_t a = uint256_t("1234567890987654321234567890123456789");
uint256_t b = uint256_t("9876543212345678909876543212123456789");
std::cout << (a + b) << std::endl;
std::cout << (a * b) << std::endl;
return 0;
}
OUTPUT
./a.out
237874615448440434220169051638465177762582290
36648625081468363373803679961248846042639268817955195957743481078122978838353
Correct answer

  • a+b
    11111111103333333231111111102246913578
  • a*b
    12193263123914037344916934337936290111422040471112635358890413056750190521

What I'm doing wrong?

Thanks

Multiplication Algorithms

What multiplication algorithm are you using here for uint128_t and uint256_t? I don’t see this algorithm in your integer repository... why?

performance

when using uint128_t i am getting constant underruns when using divide while uint64_t has no underruns
| | | |--99.24%-- AudioTime::update(unsigned long, SoundRecordingAudioData*)
| | | | |--2.14%-- [hit in function]
| | | | |
| | | | |--84.84%-- uint128_t::operator/(uint128_t const&) const
| | | | | |
| | | | | |--98.44%-- uint128_t::divmod(uint128_t const&, uint128_t const&) const
| | | | | | |--4.89%-- [hit in function]
| | | | | | |
| | | | | | |--39.88%-- uint128_t::operator<<=(uint128_t const&)
| | | | | | | |--16.91%-- [hit in function]
| | | | | | | |
| | | | | | | |--49.84%-- uint128_t::operator<<(uint128_t const&) const
| | | | | | | | |--80.93%-- [hit in function]
| | | | | | | | |
| | | | | | | | |--17.95%-- uint128_t::uint128_t<unsigned long, unsigned long, void>(unsigned long const&, unsigned long const&)
| | | | | | | | |
| | | | | | | | --1.12%-- @plt
| | | | | | | |
| | | | | | | |--30.34%-- uint128_t::operator=(uint128_t&&)
| | | | | | | | |--76.11%-- [hit in function]
| | | | | | | | |
| | | | | | | | |--13.07%-- libAudioEngine.so[+237f4]
| | | | | | | | |
| | | | | | | | |--5.46%-- libAudioEngine.so[+237f8]
| | | | | | | | |
| | | | | | | | |--3.65%-- libAudioEngine.so[+23800]
| | | | | | | | |
| | | | | | | | --1.72%-- libAudioEngine.so[+237f0]
| | | | | | | |
| | | | | | | --2.91%-- @plt
| | | | | | |
| | | | | | |--15.85%-- uint128_t uint128_t::operator>><unsigned int, unsigned int>(unsigned int const&) const
| | | | | | | |--17.90%-- [hit in function]
| | | | | | | |
| | | | | | | |--70.96%-- uint128_t::operator>>(uint128_t const&) const
| | | | | | | | |--78.27%-- [hit in function]
| | | | | | | | |
| | | | | | | | --21.73%-- uint128_t::uint128_t<unsigned long, unsigned long, void>(unsigned long const&, unsigned long const&)
| | | | | | | |
| | | | | | | |--9.65%-- uint128_t::uint128_t<unsigned int, unsigned int>(unsigned int const&)
| | | | | | | |
| | | | | | | --1.49%-- @plt
| | | | | | |
| | | | | | |--13.97%-- uint128_t::operator>=(uint128_t const&) const
| | | | | | | |--25.04%-- [hit in function]
| | | | | | | |
| | | | | | | |--39.33%-- uint128_t::operator>(uint128_t const&) const
| | | | | | | |
| | | | | | | |--29.10%-- uint128_t::operator==(uint128_t const&) const
| | | | | | | |
| | | | | | | --6.52%-- @plt
| | | | | | |
| | | | | | |--7.61%-- uint128_t::operator-=(uint128_t const&)
| | | | | | | |--8.57%-- [hit in function]
| | | | | | | |
| | | | | | | |--53.32%-- uint128_t::operator-(uint128_t const&) const
| | | | | | | | |--76.59%-- [hit in function]
| | | | | | | | |
| | | | | | | | |--17.53%-- uint128_t::uint128_t<unsigned long, unsigned long, void>(unsigned long const&, unsigned long const&)
| | | | | | | | |
| | | | | | | | |--5.85%-- @plt
| | | | | | | | |
| | | | | | | | --0.03%-- [kernel.kallsyms][+ffffff8008125282]
| | | | | | | | [kernel.kallsyms][+ffffff8008ceb91a]
| | | | | | | | [kernel.kallsyms][+ffffff8008ceb662]
| | | | | | | | [kernel.kallsyms][+ffffff80084c7a6c]
| | | | | | | |
| | | | | | | |--35.07%-- uint128_t::operator=(uint128_t&&)
| | | | | | | | |--73.47%-- [hit in function]
| | | | | | | | |
| | | | | | | | |--9.13%-- libAudioEngine.so[+237f4]
| | | | | | | | |
| | | | | | | | |--8.70%-- libAudioEngine.so[+23800]
| | | | | | | | |
| | | | | | | | --8.70%-- libAudioEngine.so[+237f8]
| | | | | | | |
| | | | | | | --3.04%-- @plt
| | | | | | |
| | | | | | |--7.28%-- uint128_t uint128_t::operator&<int, int>(int const&) const
| | | | | | | |--62.94%-- [hit in function]
| | | | | | | |
| | | | | | | |--24.83%-- uint128_t::uint128_t<int, unsigned long, void>(int const&, unsigned long const&)
| | | | | | | |
| | | | | | | --12.23%-- @plt
| | | | | | |
| | | | | | |--3.87%-- uint128_t::operator++()
| | | | | | | |--12.13%-- [hit in function]
| | | | | | | |
| | | | | | | |--81.78%-- uint128_t::operator+=(uint128_t const&)
| | | | | | | |
| | | | | | | --6.09%-- @plt
| | | | | | |
| | | | | | |--2.06%-- @plt
| | | | | | |
| | | | | | |--1.90%-- uint128_t::operator bool() const
| | | | | | |
| | | | | | |--1.83%-- uint128_t::bits() const
| | | | | | |
| | | | | | |--0.44%-- uint128_t::operator<<(uint128_t const&) const
| | | | | | |
| | | | | | |--0.21%-- uint128_t::operator=(uint128_t&&)
| | | | | | |
| | | | | | --0.21%-- std::__ndk1::pair<uint128_t, uint128_t>::pair<true, false>(uint128_t const&, uint128_t const&)
| | | | | | uint128_t::uint128_t(uint128_t const&)
| | | | | |
| | | | | |--0.70%-- uint128_t::operator<<=(uint128_t const&)
| | | | | |
| | | | | |--0.44%-- uint128_t::operator++()
| | | | | |
| | | | | |--0.21%-- uint128_t::operator>=(uint128_t const&) const
| | | | | |
| | | | | --0.20%-- uint128_t uint128_t::operator>><unsigned int, unsigned int>(unsigned int const&) const
| | | | |

can we please eliminate this compiler warning?

When rhs is bool, then the check:

if(rhs < 0) // always return false, compiler gives warning
In file included from uint128_t/uint128_t.build:7,
                 from uint128_t/uint128_t.cpp:1:
uint128_t/uint128_t.include: In instantiation of ‘uint128_t::uint128_t(const T&) [with T = bool; <template-parameter-1-2> = bool]’:
uint128_t/uint128_t.cpp:492:25:   required from here
uint128_t/uint128_t.include:83:25: warning: comparison of constant ‘0’ with boolean expression is always false [-Wbool-compare]
   83 |                 if (rhs < 0) {
      |                     ~~~~^~~

The fix should be simple, just cast it to any integer type

diff --git a/uint128_t.cpp b/uint128_t.cpp
index 569820b..017e4ee 100644
--- a/uint128_t.cpp
+++ b/uint128_t.cpp
@@ -453,7 +453,7 @@ std::string uint128_t::str(uint8_t base, const unsigned int & len) const{
 }

 uint128_t operator<<(const bool & lhs, const uint128_t & rhs){
-    return uint128_t(lhs) << rhs;
+    return uint128_t((uint8_t)(lhs)) << rhs;
 }

 uint128_t operator<<(const uint8_t & lhs, const uint128_t & rhs){
@@ -489,7 +489,7 @@ uint128_t operator<<(const int64_t & lhs, const uint128_t & rhs){
 }

 uint128_t operator>>(const bool & lhs, const uint128_t & rhs){
-    return uint128_t(lhs) >> rhs;
+    return uint128_t((uint8_t)(lhs)) >> rhs;
 }

 uint128_t operator>>(const uint8_t & lhs, const uint128_t & rhs){

uint128_t name usage

I hope I am not splitting too many hairs, but the _t suffix is reserved for the language by the C standard. You should not use it for your type. I've always observed it in C++ programs, too.

You should probably put your type in a namespace, too. I can imagine what the collisions are going to look like.

Promote to C++ standard

How can we elevate this data type into the official C++ standard, so that 128 bit integers just work out of the box?

Note that clang / gcc already have 128 bit integers. This library could detect the compilers and automatically map the type accordingly.

The major compiler laggard is MSVC, which currently offers 64 bit integers. When the user is building with MSVC, then the 128 bit type can be implemented in terms of these high and low 64 bit integer types.

any plans to add hash function

Hi,

nice one. Are there plans to add hash function to be able to use uint128_t with std::map, std::set, std::unordered_map, std::unordered_set?

Many thanx and

Best regards
Andreas

How to use this in a project?

Hi, sorry if this comes off as noobish but I don't understand how I can use this in a small project.
E.g. if I have a simple main.cpp with nothing but a main() in it, how is it included? Do you copy all the .cpp and .h files in the repository to the root of your project, #include the correct .h file and then use the classes/functions that are provided? Do all the bitwise operations work just like as they would in normal integers (e.g. u64)?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.