2 # mal (Make a Lisp) number types
5 ifndef __mal_numbers_included
6 __mal_numbers_included
:= true
8 _TOP_DIR
:= $(dir $(lastword
$(MAKEFILE_LIST
)))
9 include $(_TOP_DIR
)util.mk
11 LIST20_X
:= x x x x x x x x x x x x x x x x x x x x
12 LIST100_X
:= $(foreach x
,$(LIST20_X
),X X X X X
)
13 LIST100_0
:= $(foreach x
,$(LIST20_X
),0 0 0 0 0)
14 LIST100_9
:= $(foreach x
,$(LIST20_X
),9 9 9 9 9)
17 ### general numeric utility functions
20 int_encode
= $(strip $(call _reverse
,\
21 $(eval __temp
:= $(1))\
22 $(foreach a
,- 0 1 2 3 4 5 6 7 8 9,\
23 $(eval __temp
:= $$(subst $$a,$$a$$(SPACE
),$(__temp
))))$(__temp
)))
25 int_decode
= $(strip $(call _join
,$(call _reverse
,$(1))))
27 # trim extaneous zero digits off the end (front of number)
28 _trim_zeros
= $(if
$(call _EQ
,0,$(strip $(1))),0,$(if
$(call _EQ
,0,$(word 1,$(1))),$(call _trim_zeros
,$(wordlist
2,$(words $(1)),$(1))),$(1)))
29 trim_zeros
= $(strip \
30 $(if
$(call _EQ
,0,$(strip $(filter-out -,$(1)))),\
31 $(filter-out -,$(1)),\
32 $(call _reverse
,$(call _trim_zeros
,$(call _reverse
,$(filter-out -,$(1))))))\
33 $(if
$(filter -,$(1)), -,))
35 # drop the last element of a list of words/digits
36 drop_last
= $(call _reverse
,$(wordlist
2,$(words $(1)),$(call _reverse
,$(1))))
38 ### utility function tests
40 #$(info $(filter-out 1,$(filter 1%,1 132 456)))
41 #$(info (int_encode 13): [$(call int_encode,13)])
42 #$(info (int_encode 156463): [$(call int_encode,156463)])
43 #$(info (int_encode -156463): [$(call int_encode,-156463)])
44 #$(info (int_decode (int_encode 156463)): [$(call int_decode,$(call int_encode,156463))])
46 #$(info trim_zeros(0 0 0): [$(call trim_zeros,0 0 0)])
47 #$(info trim_zeros(0 0 0 -): [$(call trim_zeros,0 0 0 -)])
54 # compare two digits and return 'true' if digit 1 is less than or
56 _lte_digit
= $(strip \
57 $(if
$(call _EQ
,$(1),$(2)),\
59 $(if
$(call _EQ
,0,$(1)),\
61 $(if
$(wordlist
$(1),$(2),$(LIST20_X
)),\
65 # compare two lists of digits (MSB->LSB) of equal length and return
66 # 'true' if number 1 is less than number 2
67 _lte_digits
= $(strip \
69 $(if
$(call _EQ
,$(word 1,$(1)),$(word 1,$(2))),\
70 $(call _lte_digits
,$(wordlist
2,$(words $(1)),$(1)),$(wordlist
2,$(words $(2)),$(2))),\
71 $(if
$(call _lte_digit
,$(word 1,$(1)),$(word 1,$(2))),true
,)),\
74 ### lte/less than or equal to
76 _int_lte_encoded
= $(strip \
77 $(foreach len1
,$(words $(1)),$(foreach len2
,$(words $(2)),\
78 $(if
$(call _EQ
,$(len1
),$(len2
)),\
79 $(call _lte_digits
,$(call _reverse
,$(1)),$(call _reverse
,$(2))),\
80 $(if
$(wordlist
$(len1
),$(len2
),$(LIST100_X
)),\
84 int_lte_encoded
= $(strip \
85 $(if
$(filter -,$(1)),\
86 $(if
$(filter -,$(2)),\
87 $(call _int_lte_encoded
,$(filter-out -,$(2)),$(filter-out -,$(1))),\
89 $(if
$(filter -,$(2)),\
91 $(call _int_lte_encoded
,$(1),$(2)))))
93 int_lte
= $(call int_lte_encoded
,$(call int_encode
,$(1)),$(call int_encode
,$(2)))
97 int_lt_encoded
= $(strip \
98 $(if
$(call _EQ
,$(strip $(1)),$(strip $(2))),\
100 $(call int_lte_encoded
,$(1),$(2))))
102 int_lt
= $(call int_lt_encoded
,$(call int_encode
,$(1)),$(call int_encode
,$(2)))
104 ### gte/greater than or equal to
106 int_gte_encoded
= $(strip \
107 $(if
$(call _EQ
,$(strip $(1)),$(strip $(2))),\
109 $(if
$(call int_lte_encoded
,$(1),$(2)),,true
)))
111 int_gte
= $(call int_gte_encoded
,$(call int_encode
,$(1)),$(call int_encode
,$(2)))
115 int_gt_encoded
= $(strip \
116 $(if
$(call _EQ
,$(strip $(1)),$(strip $(2))),\
118 $(call int_gte_encoded
,$(1),$(2))))
120 int_gt
= $(call int_gt_encoded
,$(call int_encode
,$(1)),$(call int_encode
,$(2)))
122 #$(info _lte_digit,7,8: [$(call _lte_digit,7,8)])
123 #$(info _lte_digit,8,8: [$(call _lte_digit,8,8)])
124 #$(info _lte_digit,2,1: [$(call _lte_digit,2,1)])
125 #$(info _lte_digit,0,0: [$(call _lte_digit,0,0)])
126 #$(info _lte_digit,0,1: [$(call _lte_digit,0,1)])
127 #$(info _lte_digit,1,0: [$(call _lte_digit,1,0)])
129 #$(info _lte_digits,1 2 3,1 2 4: [$(call _lte_digits,1 2 3,1 2 4)])
130 #$(info _lte_digits,1 2 4,1 2 4: [$(call _lte_digits,1 2 4,1 2 4)])
131 #$(info _lte_digits,1 2 5,1 2 4: [$(call _lte_digits,1 2 5,1 2 4)])
132 #$(info _lte_digits,4 1,9 0: [$(call _lte_digits,4 1,9 0)])
134 # The main comparison operator (others are built on this)
135 #$(info int_lte_encoded,1,1: [$(call int_lte_encoded,1,1)])
136 #$(info int_lte_encoded,1,2: [$(call int_lte_encoded,1,2)])
137 #$(info int_lte_encoded,2,1: [$(call int_lte_encoded,2,1)])
138 #$(info int_lte_encoded,0,3: [$(call int_lte_encoded,0,3)])
139 #$(info int_lte_encoded,3,0: [$(call int_lte_encoded,3,0)])
140 #$(info int_lte_encoded,1 4,0 9: [$(call int_lte_encoded,1 4,0 9)])
141 #$(info int_lte_encoded,4 3 2 1,4 3 2 1: [$(call int_lte_encoded,4 3 2 1,4 3 2 1)])
142 #$(info int_lte_encoded,5 3 2 1,4 3 2 1: [$(call int_lte_encoded,5 3 2 1,4 3 2 1)])
143 #$(info int_lte_encoded,4 3 2 1,5 3 2 1: [$(call int_lte_encoded,4 3 2 1,5 3 2 1)])
145 #$(info int_lte_encoded,7 -,7: [$(call int_lte_encoded,7 -,7)])
146 #$(info int_lte_encoded,7,7 -: [$(call int_lte_encoded,7,7 -)])
147 #$(info int_lte_encoded,7 -,7 -: [$(call int_lte_encoded,7 -,7 -)])
148 #$(info int_lte_encoded,1 7 -,0 7: [$(call int_lte_encoded,1 7 -,0 7)])
149 #$(info int_lte_encoded,1 7,0 7 -: [$(call int_lte_encoded,1 7,0 7 -)])
150 #$(info int_lte_encoded,1 7 -,0 7 -: [$(call int_lte_encoded,1 7 -,0 7 -)])
151 #$(info int_lte_encoded,4 3 2 1 -,4 3 2 1: [$(call int_lte_encoded,4 3 2 1 -,4 3 2 1)])
152 #$(info int_lte_encoded,4 3 2 1,4 3 2 1 -: [$(call int_lte_encoded,4 3 2 1,4 3 2 1 -)])
153 #$(info int_lte_encoded,4 3 2 1 -,4 3 2 1 -: [$(call int_lte_encoded,4 3 2 1 -,4 3 2 1 -)])
155 #$(info int_lte,1,1: [$(call int_lte,1,1)])
156 #$(info int_lte,1,2: [$(call int_lte,1,2)])
157 #$(info int_lte,2,1: [$(call int_lte,2,1)])
158 #$(info int_lte,0,3: [$(call int_lte,0,3)])
159 #$(info int_lte,3,0: [$(call int_lte,3,0)])
160 #$(info int_lte,1234,1234: [$(call int_lte,1234,1234)])
161 #$(info int_lte,1235,1234: [$(call int_lte,1235,1234)])
162 #$(info int_lte,1234,1235: [$(call int_lte,1234,1235)])
163 #$(info int_lte,-1234,1235: [$(call int_lte,-1234,1235)])
164 #$(info int_lte,1234,-1235: [$(call int_lte,1234,-1235)])
165 #$(info int_lte,-1234,-1235: [$(call int_lte,-1234,-1235)])
167 #$(info int_lt,1,1: [$(call int_lt,1,1)])
168 #$(info int_lt,1,2: [$(call int_lt,1,2)])
169 #$(info int_lt,2,1: [$(call int_lt,2,1)])
170 #$(info int_lt,0,3: [$(call int_lt,0,3)])
171 #$(info int_lt,3,0: [$(call int_lt,3,0)])
172 #$(info int_lt,1234,1234: [$(call int_lt,1234,1234)])
173 #$(info int_lt,1235,1234: [$(call int_lt,1235,1234)])
174 #$(info int_lt,1234,1235: [$(call int_lt,1234,1235)])
176 #$(info int_gte,1,1: [$(call int_gte,1,1)])
177 #$(info int_gte,1,2: [$(call int_gte,1,2)])
178 #$(info int_gte,2,1: [$(call int_gte,2,1)])
179 #$(info int_gte,0,3: [$(call int_gte,0,3)])
180 #$(info int_gte,3,0: [$(call int_gte,3,0)])
181 #$(info int_gte,1234,1234: [$(call int_gte,1234,1234)])
182 #$(info int_gte,1235,1234: [$(call int_gte,1235,1234)])
183 #$(info int_gte,1234,1235: [$(call int_gte,1234,1235)])
185 #$(info int_gt,1,1: [$(call int_gt,1,1)])
186 #$(info int_gt,1,2: [$(call int_gt,1,2)])
187 #$(info int_gt,2,1: [$(call int_gt,2,1)])
188 #$(info int_gt,0,3: [$(call int_gt,0,3)])
189 #$(info int_gt,3,0: [$(call int_gt,3,0)])
190 #$(info int_gt,1234,1234: [$(call int_gt,1234,1234)])
191 #$(info int_gt,1235,1234: [$(call int_gt,1235,1234)])
192 #$(info int_gt,1234,1235: [$(call int_gt,1234,1235)])
193 #$(info int_gt,-1234,1235: [$(call int_gt,-1234,1235)])
194 #$(info int_gt,-1234,-1235: [$(call int_gt,-1234,-1235)])
202 # add_digits_with_carry
203 _add_digit
= $(words $(if
$(strip $(1)),$(wordlist
1,$(1),$(LIST20_X
)),) \
204 $(if
$(strip $(2)),$(wordlist
1,$(2),$(LIST20_X
)),))
206 # add one to a single digit
207 _inc_digit
= $(words $(wordlist
1,$(if
$(1),$(1),0),$(LIST20_X
)) x
)
209 # add two encoded numbers digit by digit without resolving carries
210 # (each digit will be larger than 9 if there is a carry value)
211 _add
= $(if
$(1)$(2),$(call _add_digit
,$(word 1,$(1)),$(word 1,$(2))) $(call _add
,$(wordlist
2,$(words $(1)),$(1)),$(wordlist
2,$(words $(2)),$(2))),)
213 # take the result of _add and resolve the carry values digit by digit
214 _resolve_carries
= $(strip \
216 $(foreach num
,$(word 1,$(1)),\
217 $(if
$(filter-out 1,$(filter 1%,$(num
))),\
218 $(call _resolve_carries
,$(call _inc_digit
,$(word 2,$(1))) $(wordlist
3,$(words $(1)),$(1)),$(2) $(patsubst 1%,%,$(num
))),\
219 $(call _resolve_carries
,$(wordlist
2,$(words $(1)),$(1)),$(2) $(num
)))),\
223 $(if
$(call _EQ
,0,$(strip $(1))),\
225 $(if
$(filter -,$(1)),$(filter-out -,$(1)),$(1) -)))
227 # add two encoded numbers, returns encoded number
228 _int_add_encoded
= $(call _resolve_carries
,$(call _add
,$(1),$(2)))
230 int_add_encoded
= $(strip \
231 $(if
$(filter -,$(1)),\
232 $(if
$(filter -,$(2)),\
233 $(call _negate
,$(call _int_add_encoded
,$(filter-out -,$(1)),$(filter-out -,$(2)))),\
234 $(call int_sub_encoded
,$(2),$(filter-out -,$(1)))),\
235 $(if
$(filter -,$(2)),\
236 $(call int_sub_encoded
,$(1),$(filter-out -,$(2))),\
237 $(call _int_add_encoded
,$(1),$(2)))))
239 # add two unencoded numbers, returns unencoded number
240 int_add
= $(call int_decode
,$(call int_add_encoded
,$(call int_encode
,$(1)),$(call int_encode
,$(2))))
244 #$(info _add_digit(7,6,1): [$(call _add_digit,7,6,1)])
245 #$(info _add_digit(7,6,0): [$(call _add_digit,7,6,0)])
246 #$(info _add_digit(7,6,0): [$(call _add_digit,7,6,0)])
247 #$(info _carries(12 14 15): [$(call _carries,12 14 15)])
248 #$(info _inc_digit(0): $(call _inc_digit,0))
249 #$(info _inc_digit(1): $(call _inc_digit,1))
250 #$(info _inc_digit(9): $(call _inc_digit,9))
251 #$(info _inc_digit(18): $(call _inc_digit,18))
252 #$(info int_add_encoded(0,0): [$(call int_add_encoded,0,0)])
254 #$(info int_add(1,2): [$(call int_add,1,2)])
255 #$(info int_add(9,9): [$(call int_add,9,9)])
256 #$(info int_add(0,9): [$(call int_add,0,9)])
257 #$(info int_add(9,0): [$(call int_add,9,0)])
258 #$(info int_add(0,0): [$(call int_add,0,0)])
259 #$(info int_add(123,456): [$(call int_add,123,456)])
260 #$(info int_add(678,789): [$(call int_add,678,789)])
261 #$(info int_add(1,12): [$(call int_add,1,12)])
262 #$(info int_add(123,5): [$(call int_add,123,5)])
263 #$(info int_add(123456,9): [$(call int_add,123456,9)])
264 #$(info int_add(999999991,9): [$(call int_add,999999991,9)])
266 #$(info int_add(-2,2): [$(call int_add,-2,2)])
267 #$(info int_add(-1,2): [$(call int_add,-1,2)])
268 #$(info int_add(1,-2): [$(call int_add,1,-2)])
269 #$(info int_add(-1,-2): [$(call int_add,-1,-2)])
275 _get_zeros
= $(if
$(call _EQ
,0,$(word 1,$(1))),$(call _get_zeros
,$(wordlist
2,$(words $(1)),$(1)),$(2) 0),$(2))
277 # return a 9's complement of a single digit
278 _complement9
= $(strip \
279 $(if
$(call _EQ
,0,$(1)),9,\
280 $(if
$(call _EQ
,1,$(1)),8,\
281 $(if
$(call _EQ
,2,$(1)),7,\
282 $(if
$(call _EQ
,3,$(1)),6,\
283 $(if
$(call _EQ
,4,$(1)),5,\
284 $(if
$(call _EQ
,5,$(1)),4,\
285 $(if
$(call _EQ
,6,$(1)),3,\
286 $(if
$(call _EQ
,7,$(1)),2,\
287 $(if
$(call _EQ
,8,$(1)),1,\
288 $(if
$(call _EQ
,9,$(1)),0)))))))))))
290 # return a 10's complement of a single digit
291 _complement10
= $(call _inc_digit
,$(call _complement9
,$(1)))
294 _complement_rest
= $(if
$(strip $(1)),\
296 $(call _complement10
,$(word 1,$(1))) \
297 $(foreach digit
,$(wordlist
2,$(words $(1)),$(1)),\
298 $(call _complement9
,$(digit
)))),)
300 # return the complement of a number
301 _complement
= $(strip $(call _get_zeros
,$(1)) \
302 $(call _complement_rest
,$(wordlist
$(call _inc_digit
,$(words $(call _get_zeros
,$(1)))),$(words $(1)),$(1))))
304 # subtracted encoded number 2 from encoded number 1 and return and
305 # encoded number result. both numbers must be positive but may have
307 __int_sub_encoded
= $(strip \
310 $(call int_add_encoded
,\
312 $(wordlist
1,$(words $(1)),$(call _complement
,$(2)) $(LIST100_9
))))))
314 _int_sub_encoded
= $(strip \
315 $(if
$(call _EQ
,0,$(strip $(2))),\
317 $(if
$(call _int_lte_encoded
,$(2),$(1)),\
318 $(call __int_sub_encoded
,$(1),$(2)),\
319 $(call _negate
,$(call __int_sub_encoded
,$(2),$(1))))))
321 int_sub_encoded
= $(strip \
322 $(if
$(filter -,$(1)),\
323 $(if
$(filter -,$(2)),\
324 $(call _int_sub_encoded
,$(filter-out -,$(2)),$(filter-out -,$(1))),\
325 $(call _negate
,$(call _int_add_encoded
,$(filter-out -,$(1)),$(2)))),\
326 $(if
$(filter -,$(2)),\
327 $(call _int_add_encoded
,$(1),$(filter-out -,$(2))),\
328 $(call _int_sub_encoded
,$(1),$(2)))))
330 # subtract unencoded number 2 from unencoded number 1 and return
332 int_sub
= $(call int_decode
,$(call int_sub_encoded
,$(call int_encode
,$(1)),$(call int_encode
,$(2))))
334 ### subtraction tests
336 #$(info _get_zeros(5 7): [$(call _get_zeros,5 7)])
337 #$(info _get_zeros(0 0 0 2): [$(call _get_zeros,0 0 0 2)])
338 #$(info _get_zeros(0 0 0 2 5): [$(call _get_zeros,0 0 0 2 5)])
340 #$(info _complement(0): [$(call _complement,0)])
341 #$(info _complement(1): [$(call _complement,1)])
342 #$(info _complement(9): [$(call _complement,9)])
343 #$(info _complement(5 7): [$(call _complement,5 7)])
344 #$(info _complement(0 0 0 2): [$(call _complement,0 0 0 2)])
345 #$(info _complement(0 0 0 5 4 3 2 1): [$(call _complement,0 0 0 5 4 3 2 1)])
347 #$(info int_sub_encoded(0 0 1, 3 1): [$(call int_sub_encoded,0 0 1,3 1)])
348 #$(info int_sub_encoded(2, 2): [$(call int_sub_encoded,2,2)])
350 #$(info int_sub(2,1): [$(call int_sub,2,1)])
351 #$(info int_sub(2,0): [$(call int_sub,2,0)])
352 #$(info int_sub(2,2): [$(call int_sub,2,2)])
353 #$(info int_sub(100,13): [$(call int_sub,100,13)])
354 #$(info int_sub(100,99): [$(call int_sub,100,99)])
355 #$(info int_sub(91,19): [$(call int_sub,91,19)])
357 #$(info int_sub(1,2): [$(call int_sub,1,2)])
358 #$(info int_sub(-1,2): [$(call int_sub,-1,2)])
359 #$(info int_sub(1,-2): [$(call int_sub,1,-2)])
360 #$(info int_sub(-1,-2): [$(call int_sub,-1,-2)])
361 #$(info int_sub(-2,-1): [$(call int_sub,-2,-1)])
362 #$(info int_sub(19,91): [$(call int_sub,19,91)])
363 #$(info int_sub(91,-19): [$(call int_sub,91,-19)])
364 #$(info int_sub(-91,19): [$(call int_sub,-91,19)])
365 #$(info int_sub(-91,-19): [$(call int_sub,-91,-19)])
372 # multiply two digits
373 #_mult_digit = $(words $(foreach x,$(1),$(2)))
374 _mult_digit
= $(strip \
375 $(words $(foreach x
,$(wordlist
1,$(1),$(LIST20_X
)),\
376 $(wordlist
1,$(2),$(LIST20_X
)))))
378 # multipy every digit of number 1 with number 2
379 # params: digits, digit, indent_zeros, results
380 _mult_row
= $(if
$(strip $(1)),$(call _mult_row
,$(wordlist
2,$(words $(1)),$(1)),$(2),$(3)0,$(4) $(call _mult_digit
,$(word 1,$(1)),$(2))$(3)),$(4))
382 # multiply every digit of number 2 with every digit of number 1 adding
383 # correct zero padding to the end of each result
384 # params: digits, digits, indent_zeros, results
385 _mult_each
= $(if
$(strip $(2)),$(call _mult_each
,$(1),$(wordlist
2,$(words $(2)),$(2)),$(3)0,$(4) $(call _mult_row
,$(1),$(word 1,$(2)),$(3))),$(4))
387 # add up a bunch of unencoded numbers. Basically reduce into the first number
388 _add_many
= $(if
$(word 2,$(1)),$(call _add_many
,$(call int_add
,$(word 1,$(1)),$(word 2,$(1))) $(wordlist
3,$(words $(1)),$(1))),$(1))
390 # multiply two encoded numbers, returns encoded number
391 _int_mult_encoded
= $(call trim_zeros
,$(call int_encode
,$(call _add_many
,$(call _mult_each
,$(1),$(2)))))
393 int_mult_encoded
= $(strip \
394 $(if
$(filter -,$(1)),\
395 $(if
$(filter -,$(2)),\
396 $(call _int_mult_encoded
,$(filter-out -,$(1)),$(filter-out -,$(2))),\
397 $(call _negate
,$(call _int_mult_encoded
,$(filter-out -,$(1)),$(2)))),\
398 $(if
$(filter -,$(2)),\
399 $(call _negate
,$(call _int_mult_encoded
,$(1),$(filter-out -,$(2)))),\
400 $(call _int_mult_encoded
,$(1),$(2)))))
402 # multiply two unencoded numbers, returns unencoded number
403 int_mult
= $(call int_decode
,$(call int_mult_encoded
,$(call int_encode
,$(1)),$(call int_encode
,$(2))))
405 #$(info _mult_digit(8,6): [$(call _mult_digit,8,6)])
406 #$(info _mult_digit(7,6): [$(call _mult_digit,7,6)])
407 #$(info _mult_row(8,6): [$(call _mult_row,8,6)])
408 #$(info _mult_row(8 7,6): [$(call _mult_row,8 7,6)])
409 #$(info _mult_row(8 7 3,6): [$(call _mult_row,8 7 3,6)])
410 #$(info _mult_each(8 7 6, 4 3 2): [$(call _mult_each,8 7 6,4 3 2)])
411 #$(info _add_many(123 234 345 456): [$(call _add_many,123 234 345 456)])
413 #$(info int_mult_encoded(8 7 3,6): [$(call int_mult_encoded,8 7 3,6)])
414 #$(info int_mult_encoded(8 7 3,0): [$(call int_mult_encoded,8 7 3,0)])
416 #$(info int_mult(378,6): [$(call int_mult,378,6)])
417 #$(info int_mult(678,234): [$(call int_mult,678,234)])
418 #$(info int_mult(1,23456): [$(call int_mult,1,23456)])
419 #$(info int_mult(0,23456): [$(call int_mult,0,23456)])
420 #$(info int_mult(0,0): [$(call int_mult,0,0)])
422 #$(info int_mult(-378,6): [$(call int_mult,-378,6)])
423 #$(info int_mult(678,-234): [$(call int_mult,678,-234)])
424 #$(info int_mult(-1,-23456): [$(call int_mult,-1,-23456)])
425 #$(info int_mult(0,-23456): [$(call int_mult,0,-23456)])
431 # return list of zeros needed to pad number 2 to the same length as number 1
432 _zero_pad
= $(strip $(wordlist
1,$(call int_sub
,$(words $(1)),$(words $(2))),$(LIST100_0
)))
434 # num1, num2, zero pad, result_accumulator
436 # - B = pad with zeros to make same digit length as A
439 # - A = subtract B from A
440 # - C = C + 10^(B pad.length)
442 # - if B.length < origin B.length: break
443 # - chop least significant digit of B
445 $(if
$(call int_lte_encoded
,$(3) $(2),$(1)),\
446 $(call _div
,$(call int_sub_encoded
,$(1),$(3) $(2)),$(2),$(3),$(call int_add_encoded
,$(4),$(3) 1)),\
448 $(call _div
,$(1),$(2),$(wordlist
2,$(words $(3)),$(3)),$(4)),\
451 # divide two encoded numbers, returns encoded number
452 _int_div_encoded
= $(strip \
453 $(if
$(call _EQ
,0,$(1)),\
455 $(if
$(call _EQ
,$(1),$(2)),\
457 $(if
$(call int_gt_encoded
,$(2),$(1)),\
459 $(call _div
,$(1),$(2),$(call _zero_pad
,$(1),$(2)),0)))))
461 int_div_encoded
= $(strip \
462 $(if
$(filter -,$(1)),\
463 $(if
$(filter -,$(2)),\
464 $(call _int_div_encoded
,$(filter-out -,$(1)),$(filter-out -,$(2))),\
465 $(call _negate
,$(call _int_div_encoded
,$(filter-out -,$(1)),$(2)))),\
466 $(if
$(filter -,$(2)),\
467 $(call _negate
,$(call _int_div_encoded
,$(1),$(filter-out -,$(2)))),\
468 $(call _int_div_encoded
,$(1),$(2)))))
470 # divide two unencoded numbers, returns unencoded number
471 int_div
= $(call int_decode
,$(call int_div_encoded
,$(call int_encode
,$(1)),$(call int_encode
,$(2))))
475 #$(info _zero_pad(1 2 3 4,1 3): [$(call _zero_pad,1 2 3 4,1 3)])
476 #$(info _zero_pad(1 2,1 3): [$(call _zero_pad,1 2,1 3)])
477 #$(info _zero_pad(2,1 3): [$(call _zero_pad,1 2,1 3)])
479 #$(info int_div_encoded(2,1): [$(call int_div_encoded,2,1)])
480 #$(info int_div_encoded(3,1): [$(call int_div_encoded,3,1)])
481 #$(info int_div_encoded(3,2): [$(call int_div_encoded,3,2)])
482 #$(info int_div_encoded(0,7): [$(call int_div_encoded,0,7)])
483 #$(info int_div_encoded(0 3,0 2): [$(call int_div_encoded,0 3,0 2)])
484 #$(info int_div_encoded(0 3,5): [$(call int_div_encoded,0 3,5)])
486 #$(info int_div(5,1): [$(call int_div,5,1)])
487 #$(info int_div(5,2): [$(call int_div,5,2)])
488 #$(info int_div(123,7): [$(call int_div,123,7)])
489 #$(info int_div(100,7): [$(call int_div,100,7)])
491 #$(info int_div(-5,1): [$(call int_div,-5,1)])
492 #$(info int_div(5,-2): [$(call int_div,5,-2)])
493 #$(info int_div(-123,-7): [$(call int_div,-123,-7)])
496 ### combination tests
498 # (/ (- (+ 515 (* 222 311)) 300) 41) = 1689
499 #$(info int_mult,222,311: [$(call int_mult,222,311)])
500 #$(info int_add(515,69042): [$(call int_add,515,69042)])
501 #$(info int_sub(69557,300): [$(call int_sub,69557,300)])
502 #$(info int_div(69257,41): [$(call int_div,69257,41)])
503 # (/ (- (+ 515 (* -222 311)) 300) 41) = -1678
504 #$(info int_mult,-222,311: [$(call int_mult,-222,311)])
505 #$(info int_add(515,-69042): [$(call int_add,515,-69042)])
506 #$(info int_sub(-68527,300): [$(call int_sub,-68527,300)])
507 #$(info int_div(-68827,41): [$(call int_div,-68827,41)])
509 ###############################################################