div()
标准 C 中的函数
我认为您应该查看div()
. <stdlib.h>
(它们是标准的 C 函数,并且在标准的所有版本中都有定义,尽管链接到 POSIX 规范。)
C11 标准 §7.22.6.2 规定:
div
... 函数在单个操作中计算numer / denom
和。numer % denom
请注意,C11 在 §6.5.5 中指定了整数除法(C99 类似):
当整数被除法时,/
运算符的结果是代数商,其中任何小数部分被丢弃。105)
105)这通常被称为“向零截断”。
但 C90(§6.3.5)更灵活但用处不大:
当整数被除且除法不精确时。如果两个操作数都是正数,则/
运算符的结果是小于代数商的最大整数,并且%
运算符的结果是正数。如果任一操作数为负,则/
运算符的结果是小于或等于代数商的最大整数还是大于或等于代数商的最小整数是实现定义的,结果的符号也是%
操作员。
floor_div()
请求floor_div()
使用的计算代码div()
整洁。
int floor_div(int a, int b)
{
assert(b != 0);
div_t r = div(a, b);
if (r.rem != 0 && ((a < 0) ^ (b < 0)))
r.quot--;
return r.quot;
}
测试代码
下面代码中的打印格式是针对示例数据量身定制的。%4d
(使用和贯穿始终会更好,但更广泛%-4d
)。此代码打印长度为 89 个字符的行加上换行符;更一般的布局将打印长度为 109 的行。两者都避免了 SO 上的水平滚动条。
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
static int floor_div(int a, int b)
{
assert(b != 0);
div_t r = div(a, b);
if (r.rem != 0 && ((a < 0) ^ (b < 0)))
r.quot--;
return r.quot;
}
static void test_floor_div(int n, int d)
{
assert(d != 0);
printf( "%3d/%-2d = %-3d (%3d)", +n, +d, floor_div(+n, +d), +n / +d);
printf("; %3d/%-3d = %-4d (%4d)", +n, -d, floor_div(+n, -d), +n / -d);
if (n != 0)
{
printf("; %4d/%-2d = %-4d (%4d)", -n, +d, floor_div(-n, +d), -n / +d);
printf("; %4d/%-3d = %-3d (%3d)", -n, -d, floor_div(-n, -d), -n / -d);
}
putchar('\n');
}
int main(void)
{
int numerators[] = { 0, 1, 2, 4, 9, 23, 291 };
enum { NUM_NUMERATORS = sizeof(numerators) / sizeof(numerators[0]) };
int denominators[] = { 1, 2, 3, 6, 17, 23 };
enum { NUM_DENOMINATORS = sizeof(denominators) / sizeof(denominators[0]) };
for (int i = 0; i < NUM_NUMERATORS; i++)
{
for (int j = 0; j < NUM_DENOMINATORS; j++)
test_floor_div(numerators[i], denominators[j]);
putchar('\n');
}
return 0;
}
测试输出
0/1 = 0 ( 0); 0/-1 = 0 ( 0)
0/2 = 0 ( 0); 0/-2 = 0 ( 0)
0/3 = 0 ( 0); 0/-3 = 0 ( 0)
0/6 = 0 ( 0); 0/-6 = 0 ( 0)
0/17 = 0 ( 0); 0/-17 = 0 ( 0)
0/23 = 0 ( 0); 0/-23 = 0 ( 0)
1/1 = 1 ( 1); 1/-1 = -1 ( -1); -1/1 = -1 ( -1); -1/-1 = 1 ( 1)
1/2 = 0 ( 0); 1/-2 = -1 ( 0); -1/2 = -1 ( 0); -1/-2 = 0 ( 0)
1/3 = 0 ( 0); 1/-3 = -1 ( 0); -1/3 = -1 ( 0); -1/-3 = 0 ( 0)
1/6 = 0 ( 0); 1/-6 = -1 ( 0); -1/6 = -1 ( 0); -1/-6 = 0 ( 0)
1/17 = 0 ( 0); 1/-17 = -1 ( 0); -1/17 = -1 ( 0); -1/-17 = 0 ( 0)
1/23 = 0 ( 0); 1/-23 = -1 ( 0); -1/23 = -1 ( 0); -1/-23 = 0 ( 0)
2/1 = 2 ( 2); 2/-1 = -2 ( -2); -2/1 = -2 ( -2); -2/-1 = 2 ( 2)
2/2 = 1 ( 1); 2/-2 = -1 ( -1); -2/2 = -1 ( -1); -2/-2 = 1 ( 1)
2/3 = 0 ( 0); 2/-3 = -1 ( 0); -2/3 = -1 ( 0); -2/-3 = 0 ( 0)
2/6 = 0 ( 0); 2/-6 = -1 ( 0); -2/6 = -1 ( 0); -2/-6 = 0 ( 0)
2/17 = 0 ( 0); 2/-17 = -1 ( 0); -2/17 = -1 ( 0); -2/-17 = 0 ( 0)
2/23 = 0 ( 0); 2/-23 = -1 ( 0); -2/23 = -1 ( 0); -2/-23 = 0 ( 0)
4/1 = 4 ( 4); 4/-1 = -4 ( -4); -4/1 = -4 ( -4); -4/-1 = 4 ( 4)
4/2 = 2 ( 2); 4/-2 = -2 ( -2); -4/2 = -2 ( -2); -4/-2 = 2 ( 2)
4/3 = 1 ( 1); 4/-3 = -2 ( -1); -4/3 = -2 ( -1); -4/-3 = 1 ( 1)
4/6 = 0 ( 0); 4/-6 = -1 ( 0); -4/6 = -1 ( 0); -4/-6 = 0 ( 0)
4/17 = 0 ( 0); 4/-17 = -1 ( 0); -4/17 = -1 ( 0); -4/-17 = 0 ( 0)
4/23 = 0 ( 0); 4/-23 = -1 ( 0); -4/23 = -1 ( 0); -4/-23 = 0 ( 0)
9/1 = 9 ( 9); 9/-1 = -9 ( -9); -9/1 = -9 ( -9); -9/-1 = 9 ( 9)
9/2 = 4 ( 4); 9/-2 = -5 ( -4); -9/2 = -5 ( -4); -9/-2 = 4 ( 4)
9/3 = 3 ( 3); 9/-3 = -3 ( -3); -9/3 = -3 ( -3); -9/-3 = 3 ( 3)
9/6 = 1 ( 1); 9/-6 = -2 ( -1); -9/6 = -2 ( -1); -9/-6 = 1 ( 1)
9/17 = 0 ( 0); 9/-17 = -1 ( 0); -9/17 = -1 ( 0); -9/-17 = 0 ( 0)
9/23 = 0 ( 0); 9/-23 = -1 ( 0); -9/23 = -1 ( 0); -9/-23 = 0 ( 0)
23/1 = 23 ( 23); 23/-1 = -23 ( -23); -23/1 = -23 ( -23); -23/-1 = 23 ( 23)
23/2 = 11 ( 11); 23/-2 = -12 ( -11); -23/2 = -12 ( -11); -23/-2 = 11 ( 11)
23/3 = 7 ( 7); 23/-3 = -8 ( -7); -23/3 = -8 ( -7); -23/-3 = 7 ( 7)
23/6 = 3 ( 3); 23/-6 = -4 ( -3); -23/6 = -4 ( -3); -23/-6 = 3 ( 3)
23/17 = 1 ( 1); 23/-17 = -2 ( -1); -23/17 = -2 ( -1); -23/-17 = 1 ( 1)
23/23 = 1 ( 1); 23/-23 = -1 ( -1); -23/23 = -1 ( -1); -23/-23 = 1 ( 1)
291/1 = 291 (291); 291/-1 = -291 (-291); -291/1 = -291 (-291); -291/-1 = 291 (291)
291/2 = 145 (145); 291/-2 = -146 (-145); -291/2 = -146 (-145); -291/-2 = 145 (145)
291/3 = 97 ( 97); 291/-3 = -97 ( -97); -291/3 = -97 ( -97); -291/-3 = 97 ( 97)
291/6 = 48 ( 48); 291/-6 = -49 ( -48); -291/6 = -49 ( -48); -291/-6 = 48 ( 48)
291/17 = 17 ( 17); 291/-17 = -18 ( -17); -291/17 = -18 ( -17); -291/-17 = 17 ( 17)
291/23 = 12 ( 12); 291/-23 = -13 ( -12); -291/23 = -13 ( -12); -291/-23 = 12 ( 12)