Public Comment Number PC-UK0095 ISO/IEC CD 9899 (SC22N2620) Public Comment =========================================== Date: 1998-02-25 Author: N.M Maclaren Author Affiliation: Self Postal Address: University of Cambridge, Computer Laboratory, New Museums Site, Pembroke Street, Cambridge CB3 3QG, United Kingdom E-mail Address: Telephone Number: +44 1223 334761 Fax Number: +44 1223 334679 Number of individual comments: 1 Comment 1. Category: Feature that should be included Committee Draft subsection: 7.14.6 Title: BCPL muldiv for multi-precision arithmetic Detailed description: The div functions have no unsigned forms, which can be a serious inconvenience for things like radix conversion and multiple length arithmetic (including some cryptographic algorithms.) There is also the vexed question of whether C has to support 64-bit integers and whether it should support 128-bit integers. It would be extremely nice for C to enable programmers to use extended integer arithmetic, without forcing every compiler writer to have to build it in. Considerable experience with BCPL and other languages is that double precision integer arithmetic can be coded efficiently in a high level language, with the exception of two primitives. These are a NxN -> 2N multiply and a 2N -> N,N divide (giving quotient and remainder), most of the functionality of which can be provided by a single composite form (i.e. NxN mod N -> N,N). BCPL had a MULDIV function, which did something like this, but it got lost somewhere in the conversion to C, and was replaced by the much more limited div function. Experience with MULDIV suggests that it could be improved for this purpose, and the improved specification is proposed here. It includes the functionality of the div functions, so there is little point in providing unsigned versions of those. It needs the obvious changes at the head of this section to the descriptions of div_t, ldiv_t and lldiv_t, and the addition of udiv_t, uldiv_t and ulldiv_t. The functions should have specifications like the following: 7.14.6.7 The muldiv function Synopsis 1 #include div_t muldiv(int a, int b, int c, int base); Description 2 The muldiv function computes the quotient and remainder of the division of the numerator a * b + c by the denominator base; if base is zero, the value INT_MAX+1 is used instead. The returned quotient is the algebraic quotient with any fractional part discarded. 3 If base is negative or if the result cannot be represented, the behaviour is undefined; otherwise quot * base + rem shall equal a * b + c. This equality shall hold as if the expressions were calculated from the values of quot, base, rem, a, b and c without overflow. Returns 4 The muldiv function returns a structure of type div_t, comprising both the quotient and the remander, as for the div function (7.14.6.2). [ Note that the reason for allowing error conditions to lead to undefined behaviour rather than flagging them is that this function is often needed in the core of a computationally intensive algorithm. RSA encryption is one example. ] 7.14.6.8 The lmuldiv function Synopsis 1 #include ldiv_t lmuldiv(long int a, long int b, long int c, long int base); Description 2 The lmuldiv function is equivalent to the muldiv function, expect that the arguments and the members of the returned structure (which has type ldiv_t) all have type long int and the value used if base is zero is LONG_MAX+1. 7.14.6.9 The llmuldiv function Synopsis 1 #include lldiv_t llmuldiv(long long int a, long long int b, long long int c, long long int base); Description 2 The llmuldiv function is equivalent to the muldiv function, expect that the arguments and the members of the returned structure (which has type lldiv_t) all have type long long int and the value used if base is zero is LLONG_MAX+1. 7.14.6.10 The umuldiv function Synopsis 1 #include udiv_t umuldiv(unsigned int a, unsigned int b, unsigned int c, unsigned int base); Description 2 The umuldiv function is equivalent to the muldiv function, expect that the arguments and the members of the returned structure (which has type udiv_t) all have type unsigned int and the value used if base is zero is UINT_MAX+1. 7.14.6.11 The ulmuldiv function Synopsis 1 #include uldiv_t ulmuldiv(unsigned long int a, unsigned long int b, unsigned long int c, unsigned long int base); Description 2 The ulmuldiv function is equivalent to the muldiv function, expect that the arguments and the members of the returned structure (which has type uldiv_t) all have type unsigned long int and the value used if base is zero is ULONG_MAX+1. 7.14.6.11 The ullmuldiv function Synopsis 1 #include ulldiv_t ullmuldiv(unsigned long long int a, unsigned long long int b, unsigned long long int c, unsigned long long int base); Description 2 The ullmuldiv function is equivalent to the muldiv function, expect that the arguments and the members of the returned structure (which has type ulldiv_t) all have type unsigned long long int and the value used if base is zero is ULLONG_MAX+1.