Path: csiph.com!eternal-september.org!feeder.eternal-september.org!nntp.eternal-september.org!eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: _BitInt(N) Date: Mon, 24 Nov 2025 05:12:12 -0800 Organization: None to speak of Lines: 70 Message-ID: <875xaz4lsj.fsf@example.invalid> References: <10dajlh$ko3c$1@dont-email.me> <10fus62$hl69$1@solani.org> <10fv2dm$3can9$1@paganini.bofh.team> <10fv40v$1f7a2$1@dont-email.me> <20251123170654.000056a9@yahoo.com> <10g18hq$28nc2$1@dont-email.me> <10g1erh$2b2cf$1@dont-email.me> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Date: Mon, 24 Nov 2025 13:12:13 +0000 (UTC) Injection-Info: dont-email.me; posting-host="497198ffef236bf75350d11e6379045b"; logging-data="2535543"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+B90RDAjhrwXq7uFlXra7c" User-Agent: Gnus/5.13 (Gnus v5.13) Cancel-Lock: sha1:OHjt48cy9r4Mo1jbmGIfzfCKpRU= sha1:Zvz4nIxR0lUs4sBpFM4cju5YC5w= Xref: csiph.com comp.lang.c:395412 bart writes: > On 24/11/2025 09:29, David Brown wrote: >> On 23/11/2025 16:06, Michael S wrote: >>> On Sun, 23 Nov 2025 13:59:59 +0000 >>> bart wrote: > >>>> So what is the result type of multiplying values of those two types? >>>> >>> >>> I think, traditional C rules for integer types apply here as well: type >>> of result is the same as type of wider operand. It is arithmetically >>> unsatisfactory, but consistent with the rest of language. >> There is one key difference between the _BitInt() types and other >> integer types - with _BitInt(), there are no automatic promotions to >> other integer types.  Thus if you are using _BitInt() operands in an >> arithmetic expression, these are not promoted to "int" or "unsigned >> int" even if they are smaller (lower rank).  If you mix _BitInt()'s >> of different sizes, then the smaller one is first converted to the >> larger type. > >>> I think, the Standard is written in such way that implementing _BitInt >>> as an arbitrary precision numbers, i.e. with number of bits held as part >>> of the data, is not allowed. > >> Correct.  _BitInt(N) is a signed integer type with precisely N value >> bits.  It can have padding bits if necessary (according to the >> target ABI), but it can't have any other information. >> >>> Of course, Language Support Library can be >>> (and hopefully is, at least for gcc; clang is messy a.t.m.) based on >>> arbitrary precision core routines, but the API used by compiler should >>> be similar to GMP's mpn_xxx family of functions rather than GMP's >>> mpz_xxx family, i.e. # of bits as separate parameters from data arrays >>> rather than combined. >>> >> Yes, exactly.  At the call site, the size of the _BitInt type is >> always a known compile-time constant, so it can easily be passed >> on.  Thus : >>     _BitInt(N) x; >>     _BitInt(M) y; >>     _BitInt(NM) z = x * y; > > So what is NM here; is it N*M (the potential maximum size of the > result), or max(N, M)? I made the same mistake in my previous post, but corrected it before posting it. The required size for the product in N+M bits, not N*M. For example, N=32, M=64 -> NM=96. [...] > How would you write a generic user function that operates on any size > BitInt? For example: > > _BitInt(?) bi_square(_BitInt(?)); I don't think you can. Each _BitInt(N) type is distinct. You could have a function that operates on arguments of type [unsigned] _BitInt(BITINT_MAXWIDTH) and depend on implicit conversions, but that's likely to be horribly inefficient. Or you can replace BITINT_MAXWIDTH by the maximum width you happen to need in your application. [...] -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com void Void(void) { Void(); } /* The recursive call of the void */