home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c      Meh, in C you gotta define EVERYTHING      243,242 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 242,157 of 243,242   
   David Brown to bart   
   Re: _BitInt(N) (1/2)   
   26 Nov 25 13:15:21   
   
   From: david.brown@hesbynett.no   
      
   On 26/11/2025 03:08, bart wrote:   
   > On 25/11/2025 23:20, Keith Thompson wrote:   
   >> bart  writes:   
   >>> On 25/11/2025 20:25, David Brown wrote:   
   >> [...]   
   >>>>    Arbitrary sized integers are a very different kettle of fish from   
   >>>> large fixed-size integers, and are not something that would fit in   
   >>>> the C language - they need a library.   
   >>>   
   >>> Really? I wouldn't have thought there was any appreciable difference   
   >>> between the code for multiplying two 100,000-bit BitInts, and that for   
   >>> multiplying two abitrary-precision ints that happen to be 100,000   
   >>> bits.   
   >>   
   >> It's not about the code that implements multiplication.  In gcc, that's   
   >> done by calling a built-in function that can operate on arbitrary data   
   >> widths.   
   >>   
   >> Think about memory management.   
   >   
   > Well, I was responding to a suggestion that BitInt support didn't need a   
   > library.   
      
   I did not say that.  (You really need to get a better understanding of   
   basic logic.)  I said that arbitrary sized integers need a library - I   
   did not say that fixed-sized integers do not need a library.   
      
   Perhaps more clearly, arbitrary sized integers need a user-visible   
   library in C.  They need functions to allocate, deallocate, and copy the   
   integers, as well as converting to and from normal integers, at a bare   
   minimum.   
      
   It is normal in C implementations that some operations are done with   
   "hidden" library calls - functions in a "language support library" that   
   you do not call directly.  On an x86 machine, "x / y" might generate a   
   divide instruction, while on a microcontroller it might generate a call   
   to a "__divide_int" function in an internal compiler-specific library   
   (with internal compiler-specific calling conventions).  _BitInt support   
   can certainly make use of such libraries, just like anything else in C.   
      
   And it looks like the gcc implementation of _BitInt /does/ use such   
   libraries for big enough _BitInt types, while using inline code for   
   sizes that can be done reasonably efficiently.  Clang, on the other   
   hand, apparently generates inline code no matter what size of _BitInt   
   you have.  Those are implementation choices, and it's all hidden from   
   the user.   
      
   >   
   > But memory management is a good point. Actual, variable-sized bigints   
   > would be awkward in C if you want to use them in ordinary expressions.   
   >   
      
   Indeed.   
      
   > Although managing large fixed-sized types, which may also involve   
   > intermediate, transient values, can have their own problems.   
      
   You already support such types in C.  If it is a problem, it is a   
   problem that every vaguely compliant C compiler has already solved.   
      
   	struct Big { uint64_t xs[250000]; }   
      
   That type is passed around, copied and assigned by value, even though it   
   is 1 MB in size.  _BigInt's don't add any new issues here.   
      
   >   
   >   
   >   
   >> Perhaps a future standard will provide a more flexible flavor of   
   >> _BitInt.  It might allow the n in _BitInt(n) to be non-constant, or   
   >> empty, or "*", to denote an arbitrary-precision integer.  But it's   
   >> hard to see how that could be done without adding other fundamental   
   >> features to the language.  And a lot of people's response would be   
   >> that if you want C++, you know where to find it.   
   >   
   > I think I would have responded better to BitInt if presented as a   
   > 'bit-set',  effectively a fixed-size bit-array, but passed by value.   
   > This is something that I'd considered myself at one time.   
      
   Certainly _BitInt's can be used as bitsets.   
      
   >   
   > Those would have logical operators, access to indvidual bits, but not   
   > arithmetic nor shifts, and no notion of twos complement. (In my   
   > implementation, they could also have been initialised like Pascal bitsets.)   
   >   
      
   _BitInt's have logical operators.  You can get access to individual bits   
   from shifts and masks, just like for any other integer types.   
      
   How efficiently a given compiler handles these is another matter -   
   expect that early implementations will be correct but relatively   
   inefficient and gradually improve as _BitInt's get more popular.   
      
   > More significantly, an unbounded version could be passed by reference,   
   > with an accompanying length (I could also use slices that have the   
   > length) as happens with arrays in C.   
      
   _BitInt's have fixed sizes - if you want a variable size, use an array.   
   No one is claiming that _BitInt types are somehow the perfect tool for   
   any use-case.   
      
   >   
   >> Similarly, C99 added complex types as a built-in language feature.   
   >> C++ added complex types as a template class, because C++ has language   
   >> features that support that kind of thing, including user-defined   
   >> literals.   
   >>   
   >> If you can think of a way to add arbitrary-precision integers to C   
   >> without other radical changes to the language, let us know.   
   >   
   > I have considered adding my actual arbitrary precision library to my   
   > systems language. It would have been superfical (such types would not be   
   > nestable within other data structures), but would have been simpler to   
   > use than function calls.   
   >   
   > Some degree of automatic memory management would have been needed   
   > (initialise locals on function entry, free on exit, deal with   
   > intermediates), but not on the C++ scale due to the restrictions.   
   >   
   > But I rejected that as being too high-level a feature, and my use-cases   
   > more suitable for a scripting language.   
      
   Different languages can support different features in different ways.  C   
   cannot support types that involve memory management in a   
   user-transparent manner - memory management is manual in C.  In C++, it   
   would be entirely possible to make arbitrary precision integers with   
   automatic memory management.  It would not even be particularly   
   difficult (except for efficient implementation of arithmetic operations   
   on large sizes), and not need any language changes.  But that would not   
   negate the uses of _BitInt, which is (AFAIUI) on its way into C++.   
      
   >   
   >   
   >> It could also be nice to be able to write code that deals with   
   >> multiple widths of _BitInt types, as we can do for arrays even   
   >> without VLAs.  But C's treatment of arrays is messy, and I'm not   
   >> sure duplicating that mess for _BitInt types would be a great idea.   
   >> And I wouldn't want to lose the ability to pass _BitInt values   
   >> to functions.   
   >>   
   >> [...]   
   >>   
   >>> So, a better fit for a struct then? Here I'm curious as to what   
   >>> BitInt(128) brings to the table.   
   >>   
   >> It brings a 128-bit integer type with constants and straightforward   
   >> assignment, comparison, and arithmetic operators.   
   >   
   > I was commenting on the ipv6 example, where structs give you that   
   > already, except arithmetic which makes little sense.   
   >   
      
      
   [continued in next message]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca