📄 20040703-1.c
字号:
/* PR 16341 */#define PART_PRECISION (sizeof (cpp_num_part) * 8)typedef unsigned int cpp_num_part;typedef struct cpp_num cpp_num;struct cpp_num{ cpp_num_part high; cpp_num_part low; int unsignedp; /* True if value should be treated as unsigned. */ int overflow; /* True if the most recent calculation overflowed. */};static intnum_positive (cpp_num num, unsigned int precision){ if (precision > PART_PRECISION) { precision -= PART_PRECISION; return (num.high & (cpp_num_part) 1 << (precision - 1)) == 0; } return (num.low & (cpp_num_part) 1 << (precision - 1)) == 0;}static cpp_numnum_trim (cpp_num num, unsigned int precision){ if (precision > PART_PRECISION) { precision -= PART_PRECISION; if (precision < PART_PRECISION) num.high &= ((cpp_num_part) 1 << precision) - 1; } else { if (precision < PART_PRECISION) num.low &= ((cpp_num_part) 1 << precision) - 1; num.high = 0; } return num;}/* Shift NUM, of width PRECISION, right by N bits. */static cpp_numnum_rshift (cpp_num num, unsigned int precision, unsigned int n){ cpp_num_part sign_mask; int x = num_positive (num, precision); if (num.unsignedp || x) sign_mask = 0; else sign_mask = ~(cpp_num_part) 0; if (n >= precision) num.high = num.low = sign_mask; else { /* Sign-extend. */ if (precision < PART_PRECISION) num.high = sign_mask, num.low |= sign_mask << precision; else if (precision < 2 * PART_PRECISION) num.high |= sign_mask << (precision - PART_PRECISION); if (n >= PART_PRECISION) { n -= PART_PRECISION; num.low = num.high; num.high = sign_mask; } if (n) { num.low = (num.low >> n) | (num.high << (PART_PRECISION - n)); num.high = (num.high >> n) | (sign_mask << (PART_PRECISION - n)); } } num = num_trim (num, precision); num.overflow = 0; return num;} #define num_zerop(num) ((num.low | num.high) == 0)#define num_eq(num1, num2) (num1.low == num2.low && num1.high == num2.high)cpp_numnum_lshift (cpp_num num, unsigned int precision, unsigned int n){ if (n >= precision) { num.overflow = !num.unsignedp && !num_zerop (num); num.high = num.low = 0; } else { cpp_num orig; unsigned int m = n; orig = num; if (m >= PART_PRECISION) { m -= PART_PRECISION; num.high = num.low; num.low = 0; } if (m) { num.high = (num.high << m) | (num.low >> (PART_PRECISION - m)); num.low <<= m; } num = num_trim (num, precision); if (num.unsignedp) num.overflow = 0; else { cpp_num maybe_orig = num_rshift (num, precision, n); num.overflow = !num_eq (orig, maybe_orig); } } return num;}unsigned int precision = 64;unsigned int n = 16;cpp_num num = { 0, 3, 0, 0 };int main(){ cpp_num res = num_lshift (num, 64, n); if (res.low != 0x30000) abort (); if (res.high != 0) abort (); if (res.overflow != 0) abort (); exit (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -