C++11标准模板(STL)- 常用数学函数 - 计算整数除法的商和余数 (std::div, std::ldiv, std::lldiv)

常用数学函数

计算整数除法的商和余数

std::div, 
std::ldiv, 
std::lldiv

定义于头文件 <cstdlib>

std::div_t     div( int x, int y );

(1)

std::ldiv_t    div( long x, long y );

(2)

std::lldiv_t   div( long long x, long long y );

(3)(C++11 起)

std::ldiv_t   ldiv( long x, long y );

(4)

std::lldiv_t lldiv( long long x, long long y );

(5)(C++11 起)

定义于头文件 <cinttypes>

std::imaxdiv_t div( std::intmax_t x, std::intmax_t y );

(6)(C++11 起)

std::imaxdiv_t imaxdiv( std::intmax_t x, std::intmax_t y );

(7)(C++11 起)

计算分子 x 除以分母 y 的商和余数

商是舍弃任何小数部分(向零截断)的代数商。余数满足 quot * y + rem == x 。

(C++11 前)

商是表达式 x/y 的结果。余数是表达式 x%y 的结果。

(C++11 起)

参数

x, y-整数值

返回值

若余数与上皆能表示成对应类型(分别为 int 、 long 、 long long 、 std::imaxdiv_t )的对象,则返回作为定义于下的 std::div_tstd::ldiv_tstd::lldiv_tstd::imaxdiv_t 类型对象的二者:

std::div_t

struct div_t { int quot; int rem; };

struct div_t { int rem; int quot; };

std::ldiv_t

struct ldiv_t { long quot; long rem; };

struct ldiv_t { long rem; long quot; };

std::lldiv_t

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

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

std::imaxdiv_t

struct imaxdiv_t { std::intmax_t quot; std::intmax_t rem; };

struct imaxdiv_t { std::intmax_t rem; std::intmax_t quot; };

若余数或商之一无法表示,则行为未定义。

注意

C++11 前,若运算数之一为负,则内建除法与取余运算符中商的舍入方向和余数的符号是实现定义的,但在 std::div 中已是良好定义。

多数平台上,单条 CPU 指令一同获得商与余数,而此函数可以活用这点,尽管编译器通常能够在适合处合并邻近的 / 与 % 。

调用示例

#include <iostream>
#include <cstdlib>
#include <typeinfo>
#include <cinttypes>

int main()
{
    //计算分子 x 除以分母 y 的商和余数
    const int iDividend = 1024;
    const int iDivisor  = 30;
    std::cout << "typeid(int).name():   " << typeid(int).name() << std::endl;
    std::div_t idiv = std::div(iDividend, iDivisor);
    std::cout << "std::div(" << iDividend << "," << iDivisor << "):   "
              << "quot: " << idiv.quot << "     "
              << "rem:  " << idiv.rem << std::endl;
    std::cout << std::endl;

    const long lDividend = 10240;
    const long lDivisor  = 30;
    std::cout << "typeid(long).name():   " << typeid(long).name() << std::endl;
    std::ldiv_t ldiv = std::div(lDividend, lDivisor);
    std::cout << "std::div(" << lDividend << "," << lDivisor << "):   "
              << "quot: " << ldiv.quot << "     "
              << "rem:  " << ldiv.rem << std::endl;
    std::cout << std::endl;

    const long long llDividend = 102400;
    const long long llDivisor  = 31;
    std::cout << "typeid(long long).name():   " << typeid(long long).name() << std::endl;
    std::lldiv_t lldiv = std::div(llDividend, llDivisor);
    std::cout << "std::div(" << llDividend << "," << llDivisor << "):   "
              << "quot: " << lldiv.quot << "     "
              << "rem:  " << lldiv.rem << std::endl;
    std::cout << std::endl;

    const long lDividend1 = 10240;
    const long lDivisor1  = 33;
    std::cout << "typeid(long).name():   " << typeid(long).name() << std::endl;
    std::ldiv_t ldiv1 = std::ldiv(lDividend1, lDivisor1);
    std::cout << "std::ldiv(" << lDividend1 << "," << lDivisor1 << "):   "
              << "quot: " << ldiv1.quot << "     "
              << "rem:  " << ldiv1.rem << std::endl;
    std::cout << std::endl;

    const long long llDividend1 = 102400;
    const long long llDivisor1  = 35;
    std::cout << "typeid(long long).name():   " << typeid(long long).name() << std::endl;
    std::lldiv_t lldiv1 = std::lldiv(llDividend1, llDivisor1);
    std::cout << "std::div(" << llDividend1 << "," << llDivisor1 << "):   "
              << "quot: " << lldiv1.quot << "     "
              << "rem:  " << lldiv1.rem << std::endl;
    std::cout << std::endl;

    const std::intmax_t intmaxDividend1 = 10240;
    const std::intmax_t intmaxDivisor1  = 33;
    std::cout << "typeid(std::intmax_t).name():   "
              << typeid(std::intmax_t).name() << std::endl;
    std::lldiv_t imaxdiv1 = std::div(std::intmax_t(intmaxDividend1), std::intmax_t(intmaxDivisor1));
    std::cout << "std::ldiv(" << intmaxDividend1 << "," << intmaxDivisor1 << "):   "
              << "quot: " << imaxdiv1.quot << "     "
              << "rem:  " << imaxdiv1.rem << std::endl;
    std::cout << std::endl;

    std::cout << "typeid(std::intmax_t).name():   "
              << typeid(std::intmax_t).name() << std::endl;
    std::imaxdiv_t imaxdiv = std::imaxdiv(std::intmax_t(intmaxDividend1), std::intmax_t(intmaxDivisor1));
    std::cout << "std::ldiv(" << intmaxDividend1 << "," << intmaxDivisor1 << "):   "
              << "quot: " << imaxdiv.quot << "     "
              << "rem:  " << imaxdiv.rem << std::endl;
    std::cout << std::endl;

    return 0;
}

输出

typeid(int).name():   i
std::div(1024,30):   quot: 34     rem:  4

typeid(long).name():   l
std::div(10240,30):   quot: 341     rem:  10

typeid(long long).name():   x
std::div(102400,31):   quot: 3303     rem:  7

typeid(long).name():   l
std::ldiv(10240,33):   quot: 310     rem:  10

typeid(long long).name():   x
std::div(102400,35):   quot: 2925     rem:  25

typeid(std::intmax_t).name():   x
std::ldiv(10240,33):   quot: 310     rem:  10

typeid(std::intmax_t).name():   x
std::ldiv(10240,33):   quot: 310     rem:  10

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值