3 #define PART_PRECISION (sizeof (cpp_num_part) * 8)
5 typedef unsigned int cpp_num_part
;
6 typedef struct cpp_num cpp_num
;
11 int unsignedp
; /* True if value should be treated as unsigned. */
12 int overflow
; /* True if the most recent calculation overflowed. */
16 num_positive (cpp_num num
, unsigned int precision
)
18 if (precision
> PART_PRECISION
)
20 precision
-= PART_PRECISION
;
21 return (num
.high
& (cpp_num_part
) 1 << (precision
- 1)) == 0;
24 return (num
.low
& (cpp_num_part
) 1 << (precision
- 1)) == 0;
28 num_trim (cpp_num num
, unsigned int precision
)
30 if (precision
> PART_PRECISION
)
32 precision
-= PART_PRECISION
;
33 if (precision
< PART_PRECISION
)
34 num
.high
&= ((cpp_num_part
) 1 << precision
) - 1;
38 if (precision
< PART_PRECISION
)
39 num
.low
&= ((cpp_num_part
) 1 << precision
) - 1;
46 /* Shift NUM, of width PRECISION, right by N bits. */
48 num_rshift (cpp_num num
, unsigned int precision
, unsigned int n
)
50 cpp_num_part sign_mask
;
51 int x
= num_positive (num
, precision
);
53 if (num
.unsignedp
|| x
)
56 sign_mask
= ~(cpp_num_part
) 0;
59 num
.high
= num
.low
= sign_mask
;
63 if (precision
< PART_PRECISION
)
64 num
.high
= sign_mask
, num
.low
|= sign_mask
<< precision
;
65 else if (precision
< 2 * PART_PRECISION
)
66 num
.high
|= sign_mask
<< (precision
- PART_PRECISION
);
68 if (n
>= PART_PRECISION
)
77 num
.low
= (num
.low
>> n
) | (num
.high
<< (PART_PRECISION
- n
));
78 num
.high
= (num
.high
>> n
) | (sign_mask
<< (PART_PRECISION
- n
));
82 num
= num_trim (num
, precision
);
86 #define num_zerop(num) ((num.low | num.high) == 0)
87 #define num_eq(num1, num2) (num1.low == num2.low && num1.high == num2.high)
90 num_lshift (cpp_num num
, unsigned int precision
, unsigned int n
)
94 num
.overflow
= !num
.unsignedp
&& !num_zerop (num
);
95 num
.high
= num
.low
= 0;
103 if (m
>= PART_PRECISION
)
111 num
.high
= (num
.high
<< m
) | (num
.low
>> (PART_PRECISION
- m
));
114 num
= num_trim (num
, precision
);
120 cpp_num maybe_orig
= num_rshift (num
, precision
, n
);
121 num
.overflow
= !num_eq (orig
, maybe_orig
);
128 unsigned int precision
= 64;
131 cpp_num num
= { 0, 3, 0, 0 };
135 cpp_num res
= num_lshift (num
, 64, n
);
137 if (res
.low
!= 0x30000)
143 if (res
.overflow
!= 0)