#
source:
trunk/third/gmp/tests/mpz/t-aorsmul.c
@
18191

Revision 18191, 5.9 KB checked in by ghudson, 22 years ago (diff) |
---|

Line | |
---|---|

1 | /* Test mpz_addmul, mpz_addmul_ui, mpz_submul, mpz_submul_ui. |

2 | |

3 | Copyright 2001, 2002 Free Software Foundation, Inc. |

4 | |

5 | This file is part of the GNU MP Library. |

6 | |

7 | The GNU MP Library is free software; you can redistribute it and/or modify |

8 | it under the terms of the GNU Lesser General Public License as published by |

9 | the Free Software Foundation; either version 2.1 of the License, or (at your |

10 | option) any later version. |

11 | |

12 | The GNU MP Library is distributed in the hope that it will be useful, but |

13 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |

14 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |

15 | License for more details. |

16 | |

17 | You should have received a copy of the GNU Lesser General Public License |

18 | along with the GNU MP Library; see the file COPYING.LIB. If not, write to |

19 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, |

20 | MA 02111-1307, USA. |

21 | */ |

22 | |

23 | |

24 | #include <stdio.h> |

25 | #include <stdlib.h> |

26 | #include <string.h> |

27 | |

28 | #include "gmp.h" |

29 | #include "gmp-impl.h" |

30 | #include "tests.h" |

31 | |

32 | |

33 | void |

34 | check_one (mpz_srcptr w, mpz_srcptr x, mpz_srcptr y) |

35 | { |

36 | mpz_t want, got; |

37 | |

38 | mpz_init (want); |

39 | mpz_init (got); |

40 | |

41 | mpz_mul (want, x, y); |

42 | mpz_add (want, w, want); |

43 | mpz_set (got, w); |

44 | mpz_addmul (got, x, y); |

45 | MPZ_CHECK_FORMAT (got); |

46 | if (mpz_cmp (want, got) != 0) |

47 | { |

48 | printf ("mpz_addmul fail\n"); |

49 | fail: |

50 | mpz_trace ("w", w); |

51 | mpz_trace ("x", x); |

52 | mpz_trace ("y", y); |

53 | mpz_trace ("want", want); |

54 | mpz_trace ("got ", got); |

55 | abort (); |

56 | } |

57 | |

58 | mpz_mul (want, x, y); |

59 | mpz_sub (want, w, want); |

60 | mpz_set (got, w); |

61 | mpz_submul (got, x, y); |

62 | MPZ_CHECK_FORMAT (got); |

63 | if (mpz_cmp (want, got) != 0) |

64 | { |

65 | printf ("mpz_submul fail\n"); |

66 | goto fail; |

67 | } |

68 | |

69 | mpz_clear (want); |

70 | mpz_clear (got); |

71 | } |

72 | |

73 | |

74 | void |

75 | check_one_ui (mpz_ptr w, mpz_ptr x, unsigned long y) |

76 | { |

77 | mpz_t want, got; |

78 | |

79 | mpz_init (want); |

80 | mpz_init (got); |

81 | |

82 | mpz_mul_ui (want, x, (unsigned long) y); |

83 | mpz_add (want, w, want); |

84 | mpz_set (got, w); |

85 | mpz_addmul_ui (got, x, (unsigned long) y); |

86 | MPZ_CHECK_FORMAT (got); |

87 | if (mpz_cmp (want, got) != 0) |

88 | { |

89 | printf ("mpz_addmul_ui fail\n"); |

90 | fail: |

91 | mpz_trace ("w", w); |

92 | mpz_trace ("x", x); |

93 | printf ("y=0x%lX %lu\n", y, y); |

94 | mpz_trace ("want", want); |

95 | mpz_trace ("got ", got); |

96 | abort (); |

97 | } |

98 | |

99 | mpz_mul_ui (want, x, y); |

100 | mpz_sub (want, w, want); |

101 | mpz_set (got, w); |

102 | mpz_submul_ui (got, x, y); |

103 | MPZ_CHECK_FORMAT (got); |

104 | if (mpz_cmp (want, got) != 0) |

105 | { |

106 | printf ("mpz_submul_ui fail\n"); |

107 | goto fail; |

108 | } |

109 | |

110 | mpz_clear (want); |

111 | mpz_clear (got); |

112 | } |

113 | |

114 | |

115 | void |

116 | check_all (mpz_ptr w, mpz_ptr x, mpz_ptr y) |

117 | { |

118 | int swap, wneg, xneg, yneg; |

119 | |

120 | MPZ_CHECK_FORMAT (w); |

121 | MPZ_CHECK_FORMAT (x); |

122 | MPZ_CHECK_FORMAT (y); |

123 | |

124 | for (swap = 0; swap < 2; swap++) |

125 | { |

126 | for (wneg = 0; wneg < 2; wneg++) |

127 | { |

128 | for (xneg = 0; xneg < 2; xneg++) |

129 | { |

130 | for (yneg = 0; yneg < 2; yneg++) |

131 | { |

132 | check_one (w, x, y); |

133 | |

134 | if (mpz_fits_ulong_p (y)) |

135 | check_one_ui (w, x, mpz_get_ui (y)); |

136 | |

137 | mpz_neg (y, y); |

138 | } |

139 | mpz_neg (x, x); |

140 | } |

141 | mpz_neg (w, w); |

142 | } |

143 | mpz_swap (x, y); |

144 | } |

145 | } |

146 | |

147 | void |

148 | check_data (void) |

149 | { |

150 | static const struct { |

151 | mp_limb_t w[6]; |

152 | mp_limb_t x[6]; |

153 | mp_limb_t y[6]; |

154 | |

155 | } data[] = { |

156 | |

157 | #define M GMP_NUMB_MAX |

158 | |

159 | /* reducing to zero */ |

160 | { { 1 }, { 1 }, { 1 } }, |

161 | { { 2 }, { 1 }, { 2 } }, |

162 | { { 0,1 }, { 0,1 }, { 1 } }, |

163 | |

164 | /* reducing to 1 */ |

165 | { { 0,1 }, { M }, { 1 } }, |

166 | { { 0,0,1 }, { M,M }, { 1 } }, |

167 | { { 0,0,0,1 }, { M,M,M }, { 1 } }, |

168 | { { 0,0,0,0,1 }, { M,M,M,M }, { 1 } }, |

169 | |

170 | /* reducing to -1 */ |

171 | { { M }, { 0,1 }, { 1 } }, |

172 | { { M,M }, { 0,0,1 }, { 1 } }, |

173 | { { M,M,M }, { 0,0,0,1 }, { 1 } }, |

174 | { { M,M,M,M }, { 0,0,0,0,1 }, { 1 } }, |

175 | |

176 | /* carry out of addmul */ |

177 | { { M }, { 1 }, { 1 } }, |

178 | { { M,M }, { 1 }, { 1 } }, |

179 | { { M,M,M }, { 1 }, { 1 } }, |

180 | |

181 | /* borrow from submul */ |

182 | { { 0,1 }, { 1 }, { 1 } }, |

183 | { { 0,0,1 }, { 1 }, { 1 } }, |

184 | { { 0,0,0,1 }, { 1 }, { 1 } }, |

185 | |

186 | /* borrow from submul */ |

187 | { { 0,0,1 }, { 0,1 }, { 1 } }, |

188 | { { 0,0,0,1 }, { 0,1 }, { 1 } }, |

189 | { { 0,0,0,0,1 }, { 0,1 }, { 1 } }, |

190 | |

191 | /* more borrow from submul */ |

192 | { { M }, { 0,1 }, { 1 } }, |

193 | { { M }, { 0,0,1 }, { 1 } }, |

194 | { { M }, { 0,0,0,1 }, { 1 } }, |

195 | { { M }, { 0,0,0,0,1 }, { 1 } }, |

196 | |

197 | /* big borrow from submul */ |

198 | { { 0,0,1 }, { M,M }, { M } }, |

199 | { { 0,0,0,1 }, { M,M }, { M } }, |

200 | { { 0,0,0,0,1 }, { M,M }, { M } }, |

201 | |

202 | /* small w */ |

203 | { { 0,1 }, { M,M }, { M } }, |

204 | { { 0,1 }, { M,M,M }, { M } }, |

205 | { { 0,1 }, { M,M,M,M }, { M } }, |

206 | { { 0,1 }, { M,M,M,M,M }, { M } }, |

207 | }; |

208 | |

209 | mpz_t w, x, y; |

210 | int i; |

211 | |

212 | mpz_init (w); |

213 | mpz_init (x); |

214 | mpz_init (y); |

215 | |

216 | for (i = 0; i < numberof (data); i++) |

217 | { |

218 | mpz_set_n (w, data[i].w, numberof(data[i].w)); |

219 | mpz_set_n (x, data[i].x, numberof(data[i].x)); |

220 | mpz_set_n (y, data[i].y, numberof(data[i].y)); |

221 | check_all (w, x, y); |

222 | } |

223 | |

224 | mpz_clear (w); |

225 | mpz_clear (x); |

226 | mpz_clear (y); |

227 | } |

228 | |

229 | |

230 | void |

231 | check_random (int argc, char *argv[]) |

232 | { |

233 | gmp_randstate_ptr rands = RANDS; |

234 | mpz_t w, x, y; |

235 | int i, reps = 2000; |

236 | |

237 | mpz_init (w); |

238 | mpz_init (x); |

239 | mpz_init (y); |

240 | |

241 | if (argc == 2) |

242 | reps = atoi (argv[1]); |

243 | |

244 | for (i = 0; i < reps; i++) |

245 | { |

246 | mpz_errandomb (w, rands, 5*BITS_PER_MP_LIMB); |

247 | mpz_errandomb (x, rands, 5*BITS_PER_MP_LIMB); |

248 | mpz_errandomb (y, rands, 5*BITS_PER_MP_LIMB); |

249 | check_all (w, x, y); |

250 | |

251 | mpz_errandomb (w, rands, 5*BITS_PER_MP_LIMB); |

252 | mpz_errandomb (x, rands, 5*BITS_PER_MP_LIMB); |

253 | mpz_errandomb (y, rands, BITS_PER_ULONG); |

254 | check_all (w, x, y); |

255 | } |

256 | |

257 | mpz_clear (w); |

258 | mpz_clear (x); |

259 | mpz_clear (y); |

260 | } |

261 | |

262 | |

263 | int |

264 | main (int argc, char *argv[]) |

265 | { |

266 | tests_start (); |

267 | mp_trace_base = -16; |

268 | |

269 | check_data (); |

270 | check_random (argc, argv); |

271 | |

272 | tests_end (); |

273 | exit (0); |

274 | } |

**Note:**See TracBrowser for help on using the repository browser.