Is the div function useful (stdlib.h)?

There is a function called div in C, C ++ (stdlib.h)

div_t div(int numer, int denom); typedef struct _div_t { int quot; int rem; } div_t; 

But C, C ++ have / and% operators.

My question is: " When there are / and% operators, is the div function useful ?"

+16
c ++ c integer-division
Jul 16 2018-11-15T00:
source share
6 answers

The div () function returns a structure that contains the factor and the remainder of dividing the first parameter (numerator) by the second (denominator). There are four options:

  • div_t div(int, int)
  • ldiv_t ldiv(long, long)
  • lldiv_t lldiv(long long, long long)
  • imaxdiv_t imaxdiv(intmax_t, intmax_t (intmax_t is the largest integer type available on the system)

The structure of div_t as follows:

 typedef struct { int quot; /* Quotient. */ int rem; /* Remainder. */ } div_t; 

The implementation simply uses the / and % operators, so this is not a very complicated or necessary function, but it is part of the C standard (as defined in [ISO 9899: 201x] [1]).

See implementation in GNU libc:

 /* Return the `div_t' representation of NUMER over DENOM. */ div_t div (numer, denom) int numer, denom; { div_t result; result.quot = numer / denom; result.rem = numer % denom; /* The ANSI standard says that |QUOT| <= |NUMER / DENOM|, where NUMER / DENOM is to be computed in infinite precision. In other words, we should always truncate the quotient towards zero, never -infinity. Machine division and remainer may work either way when one or both of NUMER or DENOM is negative. If only one is negative and QUOT has been truncated towards -infinity, REM will have the same sign as DENOM and the opposite sign of NUMER; if both are negative and QUOT has been truncated towards -infinity, REM will be positive (will have the opposite sign of NUMER). These are considered `wrong'. If both are NUM and DENOM are positive, RESULT will always be positive. This all boils down to: if NUMER >= 0, but REM < 0, we got the wrong answer. In that case, to get the right answer, add 1 to QUOT and subtract DENOM from REM. */ if (numer >= 0 && result.rem < 0) { ++result.quot; result.rem -= denom; } return result; } 
+13
Jul 16 2018-11-11T00:
source share

Yes it is: it calculates the coefficient and the remainder in one operation.

In addition, the same behavior can be achieved with / + % (and a decent optimizer optimizes them in one div anyway).

To summarize: if you care about delivering the latest bits of performance, this might be your pick feature, especially if the optimizer on your platform is not so advanced. This is often the case for embedded platforms. Otherwise, use any method that you find more readable.

+15
Jul 16 2018-11-11T00:
source share

The semantics of div () are different from the semantics of% and /, which is important in some cases. This is why the following code in the implementation is shown in the psYchotic answer:

 if (numer >= 0 && result.rem < 0) { ++result.quot; result.rem -= denom; } 

% can return a negative answer, while div () always returns a non-negative remainder.

Note the entry in WikiPedia , in particular, "the div is always rounded to 0, as opposed to the usual integer division by C, where rounding for negative numbers is implementation dependent."

+9
Jul 16 '11 at 16:26
source share

div() filled pre-C99 need: portability

Pre C99 , the direction of rounding of the factor a / b with the negative operand is implementation dependent. With div() , the rounding direction is not optional, but indicated as 0. div() provided that the figurative division is uniform. The secondary use was potential efficiency, when the code had to calculate both the factor and the remainder.

With C99 and later versions of div() and / defining the same circular direction, and with better compilers optimizing the adjacent codes a/b and a%b , the need is reduced.




This was a good reason for div() , and this explains the lack of udiv_t udiv(unsigned numer, unsigned denom) in the C specification: problems with implementation-dependent a/b results with negative operands do not exist for unsigned even in pre -C99.

+3
Sep 08 '14 at 22:39
source share

It costs less time if you need both values. The processor always calculates both the remainder and the coefficient when performing the division. If you use "/" and "%" once, the processor will calculate both numbers twice.

(forgive my poor English, I'm not native)

+2
Jul 16 2018-11-11T00:
source share

Probably because on many processors the div command produces both values, and you can always rely on the compiler to recognize that adjacent / and% operators on the same inputs can be combined into one operation.

0
Jul 16 2018-11-11T00:
source share



All Articles