c语言中除法与余数,带符号整数的除法与余数

(http://synesis.com.au/publications.html搜 conversions)。他的巧妙之处在于,用一个对称的 digits 数组搞定了负数转换的边界条件(二进制补码的正负整数表示范围不对称)。代码大致如下,经过改写:

const char* convert(char buf[], int value)

{

static char digits[19] =

{ '9', '8', '7', '6', '5', '4', '3', '2', '1',

'0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };

static const char* zero = digits + 9; // zero 指向 '0'

// works for -2147483648 .. 2147483647

int i = value;

char* p = buf;

do {

int lsd = i % 10; // lsd 可能小于 0

i /= 10; // 是向下取整还是向零取整?

*p++ = zero[lsd]; // 下标可能为负

} while (i != 0);

if (value < 0) {

*p++ = '-';

}

*p = '/0';

std::reverse(buf, p);

return p; // p - buf 即为整数长度

}

这段简短的代码对 32-bit int 的全部取值都是正确的(从-2147483648到 2147483647)。可以视为 itoa() 的参考实现,面试的标准答案。

读到这份代码,我心中顿时升起一个疑虑:《C Traps and Pitfalls》第7.7节讲到,C 语言中的整数除法(/)和取模(%)运算在操作数为负的时候,结果是 implementation-defined。(网上能下载到的一份简略版也有相同的内容,http://www.literateprogramming.com/ctraps.pdf第7.5节。)

也就是说,如果 m、d 都是整数,

int q = m / d;

你可能感兴趣的:(c语言中除法与余数)