• Re: Is there a current best library for large integers?

    From Ralf Goertz@3:633/10 to All on Mon Oct 6 17:34:56 2025
    Am Fri, 3 Oct 2025 17:05:38 +0100
    schrieb Vir Campestris <vir.campestris@invalid.invalid>:

    On 29/09/2025 23:03, Michael S wrote:
    If you neeed just a little more than 64 bit then use 128-bit
    integers. For decades gcc and clang feature a non-standard type
    __int128.
    I went away and thought about it. Then decided I'll never port this
    code, so I used __int128. I then found that you can't write it out, so
    I had to implement a string convert just to print the output!

    Your post inspired me to do that myself (without having looked at the implementations for the standard integer types or thought about that at
    all ever before). This is what I came up with. It doesn't use
    std::string to avoid overhead and respects the basefield and showbase manipulators (but only them). What do you think?

    #include <iostream>

    std::ostream& operator<<(std::ostream& out, unsigned __int128 k) {
    if (k==0) return out<<'0'; //treat 0 specially
    unsigned __int128 base(10),
    p(1); //cycles through powers of base
    auto b=(out.flags() & std::ios::basefield);
    auto sb=(out.flags() & std::ios::showbase);
    if (b & std::ios::oct) {
    base=8;
    if (sb) out<<'0'; //octal prefix
    }
    if (b & std::ios::hex) {
    base=16;
    if (sb) out<<"0x"; //hex prefix
    }
    while (k/p>=base) { //find maximum power of base ó k
    p*=base;
    }
    while (p>0) {
    unsigned __int128 d=k/p; //coefficient for current power p of bas
    e
    char c=static_cast<char>(d+'0'); //convert d to ASCII character
    if (d>9) c+='a'-'9'-1; //shift characters bigger than
    //'9' to lowercase letters for base 16
    out<<c;
    k-=d*p;
    p/=base;
    }
    return out;
    }

    std::ostream& operator<<(std::ostream& out, signed __int128 k) {
    if ((k<0) && (out.flags() & std::ios::dec)) {
    out<<'-'; //output a minus sign
    k*=-1; //change k to absolute value
    }
    return out<<static_cast<unsigned __int128>(k); //output the digits
    }



    --- PyGate Linux v1.0
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Paavo Helde@3:633/10 to All on Tue Oct 7 10:44:57 2025
    On 10/6/2025 6:34 PM, Ralf Goertz wrote:
    Am Fri, 3 Oct 2025 17:05:38 +0100
    schrieb Vir Campestris <vir.campestris@invalid.invalid>:

    On 29/09/2025 23:03, Michael S wrote:
    If you neeed just a little more than 64 bit then use 128-bit
    integers. For decades gcc and clang feature a non-standard type
    __int128.
    I went away and thought about it. Then decided I'll never port this
    code, so I used __int128. I then found that you can't write it out, so
    I had to implement a string convert just to print the output!

    Your post inspired me to do that myself (without having looked at the implementations for the standard integer types or thought about that at
    all ever before). This is what I came up with. It doesn't use
    std::string to avoid overhead and respects the basefield and showbase manipulators (but only them). What do you think?


    std::ostream& operator<<(std::ostream& out, signed __int128 k) {
    if ((k<0) && (out.flags() & std::ios::dec)) {
    out<<'-'; //output a minus sign
    k*=-1; //change k to absolute value

    Wouldn't this fail with INT128_MIN? Just nit-picking!


    --- PyGate Linux v1.0
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Ralf Goertz@3:633/10 to All on Tue Oct 7 10:51:50 2025
    Am Tue, 7 Oct 2025 10:44:57 +0300
    schrieb Paavo Helde <eesnimi@osa.pri.ee>:

    On 10/6/2025 6:34 PM, Ralf Goertz wrote:
    Am Fri, 3 Oct 2025 17:05:38 +0100
    schrieb Vir Campestris <vir.campestris@invalid.invalid>:

    On 29/09/2025 23:03, Michael S wrote:
    If you neeed just a little more than 64 bit then use 128-bit
    integers. For decades gcc and clang feature a non-standard type
    __int128.
    I went away and thought about it. Then decided I'll never port this
    code, so I used __int128. I then found that you can't write it
    out, so I had to implement a string convert just to print the
    output!

    Your post inspired me to do that myself (without having looked at
    the implementations for the standard integer types or thought about
    that at all ever before). This is what I came up with. It doesn't
    use std::string to avoid overhead and respects the basefield and
    showbase manipulators (but only them). What do you think?


    std::ostream& operator<<(std::ostream& out, signed __int128 k) {
    if ((k<0) && (out.flags() & std::ios::dec)) {
    out<<'-'; //output a minus sign
    k*=-1; //change k to absolute value

    Wouldn't this fail with INT128_MIN? Just nit-picking!

    Hm, maybe it should. But it doesn't:

    int main() {
    std::cout<<' '<<std::numeric_limits<signed __int128>::max()<<std::endl;
    std::cout<< std::numeric_limits<signed __int128>::min()<<std::endl;
    }

    gives

    170141183460469231731687303715884105727 -170141183460469231731687303715884105728

    First, I wanted to clear the sign bit ?by hand? but it seem
    ed overly
    complicated and multiplying by -1 seemed to do the trick. And wouldn't
    any method suffer from the same problem? Which might be why you added
    the nit-picking remark. :-) OTOH, one could static_cast k to unsigned
    first and then clear the bit.


    --- PyGate Linux v1.0
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Tue Oct 7 18:24:10 2025
    Am 29.09.2025 um 22:40 schrieb olcott:
    On 9/29/2025 3:08 PM, Vir Campestris wrote:
    I could knock something up - all I need to do is total a ****** lot of
    small numbers accurately, but the result is more than 64 bits.

    Andy

    Its not too hard to do this using ASCII digits.
    Then you have unlimited length.

    And how do you do the math with that ?

    --- PyGate Linux v1.0
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Tue Oct 7 17:56:16 2025
    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 29.09.2025 um 22:40 schrieb olcott:
    On 9/29/2025 3:08 PM, Vir Campestris wrote:
    I could knock something up - all I need to do is total a ****** lot of
    small numbers accurately, but the result is more than 64 bits.

    Andy

    Its not too hard to do this using ASCII digits.
    Then you have unlimited length.

    And how do you do the math with that ?

    mpz_init_set_str()

    --- PyGate Linux v1.0
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Wed Oct 8 04:38:27 2025
    Am 07.10.2025 um 19:56 schrieb Scott Lurndal:
    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 29.09.2025 um 22:40 schrieb olcott:
    On 9/29/2025 3:08 PM, Vir Campestris wrote:
    I could knock something up - all I need to do is total a ****** lot of >>>> small numbers accurately, but the result is more than 64 bits.

    Andy

    Its not too hard to do this using ASCII digits.
    Then you have unlimited length.

    And how do you do the math with that ?

    mpz_init_set_str()

    The math isn't done with ASCII for that.


    --- PyGate Linux v1.0
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Wed Oct 8 14:02:00 2025
    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 07.10.2025 um 19:56 schrieb Scott Lurndal:
    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 29.09.2025 um 22:40 schrieb olcott:
    On 9/29/2025 3:08 PM, Vir Campestris wrote:
    I could knock something up - all I need to do is total a ****** lot of >>>>> small numbers accurately, but the result is more than 64 bits.

    Andy

    Its not too hard to do this using ASCII digits.
    Then you have unlimited length.

    And how do you do the math with that ?

    mpz_init_set_str()

    The math isn't done with ASCII for that.

    So what? The input is ASCII and the output can
    be ASCII (or EBCDIC or whatever) and the length
    of the operands is limited only by the size of
    the available address space.

    There were systems in in the past that did the
    math directly on ASCII (or EBCDIC) data, such
    as the Burroughs medium systems. There, the processor
    simply ignored the zone digit. Operands could
    range from 1 to 100 digits.


    --- PyGate Linux v1.0
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)