Namespaces
Variants

div, ldiv, lldiv, imaxdiv

From cppreference.net
< c ‎ | numeric ‎ | math
Common mathematical functions
Functions
Basic operations
div ldiv lldiv imaxdiv
(C99) (C99)
(C99)
(C99)
(C99)
(C99) (C99) (C99) (C23)
Maximum/minimum operations
Exponential functions
Power functions
Trigonometric and hyperbolic functions
Nearest integer floating-point
(C99) (C99) (C99)
(C23) (C23) (C23) (C23)
Floating-point manipulation
Narrowing operations
(C23)
(C23)
(C23)
(C23)
(C23)
(C23)
Quantum and quantum exponent
Decimal re-encoding functions
Total order and payload functions
Classification
Error and gamma functions
(C99)
(C99)
(C99)
(C99)
Types
div_t ldiv_t lldiv_t imaxdiv_t
(C99) (C99)
Macro constants
Special floating-point values
Arguments and return values
Error handling
Fast operation indicators
定義先ヘッダ <stdlib.h>
div_t     div ( int x, int y ) ;
(1)
ldiv_t    ldiv ( long x, long y ) ;
(2)
lldiv_t   lldiv ( long long x, long long y ) ;
(3) (C99以降)
定義先ヘッダ <inttypes.h>
imaxdiv_t imaxdiv ( intmax_t x, intmax_t y ) ;
(4) (C99以降)

分子 x を分母 y で除算した商と余りの両方を計算します。

商と余りを同時に計算する。商は代数商から小数部分を切り捨てたもの(ゼロ方向への切り捨て)である。余りは quot * y + rem == x を満たす。

(C99まで)

商(式 x / y の結果)と余り(式 x % y の結果)を同時に計算する。

(C99以降)

目次

パラメータ

x, y - 整数値

戻り値

剰余と商の両方が対応する型のオブジェクトとして表現可能な場合(それぞれ int long long long intmax_t )、以下のように定義される型 div_t ldiv_t lldiv_t imaxdiv_t のオブジェクトとして両方を返す:

div_t

struct div_t { int quot; int rem; };

または

struct div_t { int rem; int quot; };

ldiv_t

struct ldiv_t { long quot; long rem; };

または

struct ldiv_t { long rem; long quot; };

lldiv_t

struct lldiv_t { long long quot; long long rem; };

または

struct lldiv_t { long long rem; long long quot; };

imaxdiv_t

struct imaxdiv_t { intmax_t quot; intmax_t rem; };

または

struct imaxdiv_t { intmax_t rem; intmax_t quot; };

剰余または商のいずれかが表現できない場合、動作は未定義です。

注記

C99まで、被演算子のいずれかが負の場合、組み込みの除算および剰余演算子における商の丸め方向と剰余の符号は処理系定義でしたが、 div および ldiv では明確に定義されていました。

多くのプラットフォームでは、単一のCPU命令で商と剰余の両方を取得でき、この関数はそれを活用する可能性があります。ただし、コンパイラは一般的に近接する / 演算子と % 演算子を適切にマージすることができます。

#include <assert.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
void reverse(char* first, char* last)
{
    for (--last; first < last; ++first, --last)
    {
        char c = *last;
        *last = *first;
        *first = c;
    }
}
// バッファオーバーフローの場合は空バッファを返す
char* itoa(int n, int base, char* buf, size_t buf_size)
{
    assert(2 <= base && base <= 16 && buf && buf_size);
    div_t dv = {.quot = n};
    char* p = buf;
    do
    {
        if (!--buf_size)
            return (*buf = '\0'), buf;
        dv = div(dv.quot, base);
        *p++ = "0123456789abcdef"[abs(dv.rem)];
    }
    while(dv.quot);
    if (n < 0)
        *p++ = '-';
    *p = '\0';
    reverse(buf, p);
    return buf;
}
int main(void)
{
    char buf[16];
    printf("%s\n", itoa(0, 2, buf, sizeof buf));
    printf("%s\n", itoa(007, 3, buf, sizeof buf));
    printf("%s\n", itoa(12346, 10, buf, sizeof buf));
    printf("%s\n", itoa(-12346, 10, buf, sizeof buf));
    printf("%s\n", itoa(-42, 2, buf, sizeof buf));
    printf("%s\n", itoa(INT_MAX, 16, buf, sizeof buf));
    printf("%s\n", itoa(INT_MIN, 16, buf, sizeof buf));
}

出力例:

0
21
12346
-12346
-101010
7fffffff
-80000000

参考文献

  • C23規格 (ISO/IEC 9899:2024):
  • 7.8.2.2 imaxdiv関数 (p: TBD)
  • 7.22.6.2 div, ldiv及びlldiv関数 (p: TBD)
  • C17規格 (ISO/IEC 9899:2018):
  • 7.8.2.2 imaxdiv関数 (p: 159)
  • 7.22.6.2 div, ldiv及びlldiv関数 (p: 259)
  • C11標準 (ISO/IEC 9899:2011):
  • 7.8.2.2 imaxdiv関数 (p: 219)
  • 7.22.6.2 div, ldiv及びlldiv関数 (p: 356)
  • C99規格 (ISO/IEC 9899:1999):
  • 7.8.2.2 imaxdiv関数 (p: 200)
  • 7.20.6.2 div, ldivおよびlldiv関数 (p: 320)
  • C89/C90標準 (ISO/IEC 9899:1990):
  • 4.10 div_t, ldiv_t
  • 4.10.6.2 div関数
  • 4.10.6.4 ldiv関数

関連項目

(C99) (C99)
浮動小数点除算の剰余を計算する
(関数)
浮動小数点除算の符号付き剰余を計算する
(関数)
(C99) (C99) (C99)
符号付き剰余と除算操作の下位3ビットを計算する
(関数)

外部リンク

1. Euclidean division — Wikipediaより。
2. Modulo (and Truncated division) — Wikipediaより。