xref: /freebsd/contrib/bc/gen/lib2.bc (revision a970610a3af63b3f4df5b69d91c6b4093a00ed8f)
1252884aeSStefan Eßer/*
2252884aeSStefan Eßer * *****************************************************************************
3252884aeSStefan Eßer *
43aa99676SStefan Eßer * SPDX-License-Identifier: BSD-2-Clause
5252884aeSStefan Eßer *
6*a970610aSStefan Eßer * Copyright (c) 2018-2024 Gavin D. Howard and contributors.
7252884aeSStefan Eßer *
8252884aeSStefan Eßer * Redistribution and use in source and binary forms, with or without
9252884aeSStefan Eßer * modification, are permitted provided that the following conditions are met:
10252884aeSStefan Eßer *
11252884aeSStefan Eßer * * Redistributions of source code must retain the above copyright notice, this
12252884aeSStefan Eßer *   list of conditions and the following disclaimer.
13252884aeSStefan Eßer *
14252884aeSStefan Eßer * * Redistributions in binary form must reproduce the above copyright notice,
15252884aeSStefan Eßer *   this list of conditions and the following disclaimer in the documentation
16252884aeSStefan Eßer *   and/or other materials provided with the distribution.
17252884aeSStefan Eßer *
18252884aeSStefan Eßer * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19252884aeSStefan Eßer * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20252884aeSStefan Eßer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21252884aeSStefan Eßer * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22252884aeSStefan Eßer * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23252884aeSStefan Eßer * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24252884aeSStefan Eßer * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25252884aeSStefan Eßer * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26252884aeSStefan Eßer * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27252884aeSStefan Eßer * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28252884aeSStefan Eßer * POSSIBILITY OF SUCH DAMAGE.
29252884aeSStefan Eßer *
30252884aeSStefan Eßer * *****************************************************************************
31252884aeSStefan Eßer *
32252884aeSStefan Eßer * The second bc math library.
33252884aeSStefan Eßer *
34252884aeSStefan Eßer */
35252884aeSStefan Eßer
36252884aeSStefan Eßerdefine p(x,y){
37aa339f1dSStefan Eßer	auto a,i,s,z
38aa339f1dSStefan Eßer	if(y==0)return 1@scale
39aa339f1dSStefan Eßer	if(x==0){
40aa339f1dSStefan Eßer		if(y>0)return 0
41aa339f1dSStefan Eßer		return 1/0
42aa339f1dSStefan Eßer	}
43252884aeSStefan Eßer	a=y$
44252884aeSStefan Eßer	if(y==a)return(x^a)@scale
45aa339f1dSStefan Eßer	z=0
46aa339f1dSStefan Eßer	if(x<1){
47aa339f1dSStefan Eßer		y=-y
48aa339f1dSStefan Eßer		a=-a
49aa339f1dSStefan Eßer		z=x
50aa339f1dSStefan Eßer		x=1/x
51aa339f1dSStefan Eßer	}
52aa339f1dSStefan Eßer	if(y<0){
53252884aeSStefan Eßer		return e(y*l(x))
54252884aeSStefan Eßer	}
55aa339f1dSStefan Eßer	i=x^a
56aa339f1dSStefan Eßer	s=scale
57aa339f1dSStefan Eßer	scale+=length(i)+5
58aa339f1dSStefan Eßer	if(z){
59aa339f1dSStefan Eßer		x=1/z
60aa339f1dSStefan Eßer		i=x^a
61aa339f1dSStefan Eßer	}
62aa339f1dSStefan Eßer	i*=e((y-a)*l(x))
63aa339f1dSStefan Eßer	scale=s
64aa339f1dSStefan Eßer	return i@scale
65aa339f1dSStefan Eßer}
66252884aeSStefan Eßerdefine r(x,p){
67252884aeSStefan Eßer	auto t,n
68252884aeSStefan Eßer	if(x==0)return x
69252884aeSStefan Eßer	p=abs(p)$
70252884aeSStefan Eßer	n=(x<0)
71252884aeSStefan Eßer	x=abs(x)
72252884aeSStefan Eßer	t=x@p
73252884aeSStefan Eßer	if(p<scale(x)&&x-t>=5>>p+1)t+=1>>p
74252884aeSStefan Eßer	if(n)t=-t
75252884aeSStefan Eßer	return t
76252884aeSStefan Eßer}
77252884aeSStefan Eßerdefine ceil(x,p){
78252884aeSStefan Eßer	auto t,n
79252884aeSStefan Eßer	if(x==0)return x
80252884aeSStefan Eßer	p=abs(p)$
81252884aeSStefan Eßer	n=(x<0)
82252884aeSStefan Eßer	x=abs(x)
83252884aeSStefan Eßer	t=(x+((x@p<x)>>p))@p
84252884aeSStefan Eßer	if(n)t=-t
85252884aeSStefan Eßer	return t
86252884aeSStefan Eßer}
87252884aeSStefan Eßerdefine f(n){
88252884aeSStefan Eßer	auto r
89252884aeSStefan Eßer	n=abs(n)$
90252884aeSStefan Eßer	for(r=1;n>1;--n)r*=n
91252884aeSStefan Eßer	return r
92252884aeSStefan Eßer}
93aa339f1dSStefan Eßerdefine max(a,b){
94aa339f1dSStefan Eßer	if(a>b)return a
95aa339f1dSStefan Eßer	return b
96aa339f1dSStefan Eßer}
97aa339f1dSStefan Eßerdefine min(a,b){
98aa339f1dSStefan Eßer	if(a<b)return a
99aa339f1dSStefan Eßer	return b
100aa339f1dSStefan Eßer}
101252884aeSStefan Eßerdefine perm(n,k){
102252884aeSStefan Eßer	auto f,g,s
103252884aeSStefan Eßer	if(k>n)return 0
104252884aeSStefan Eßer	n=abs(n)$
105252884aeSStefan Eßer	k=abs(k)$
106252884aeSStefan Eßer	f=f(n)
107252884aeSStefan Eßer	g=f(n-k)
108252884aeSStefan Eßer	s=scale
109252884aeSStefan Eßer	scale=0
110252884aeSStefan Eßer	f/=g
111252884aeSStefan Eßer	scale=s
112252884aeSStefan Eßer	return f
113252884aeSStefan Eßer}
114252884aeSStefan Eßerdefine comb(n,r){
115252884aeSStefan Eßer	auto s,f,g,h
116252884aeSStefan Eßer	if(r>n)return 0
117252884aeSStefan Eßer	n=abs(n)$
118252884aeSStefan Eßer	r=abs(r)$
119252884aeSStefan Eßer	s=scale
120252884aeSStefan Eßer	scale=0
121252884aeSStefan Eßer	f=f(n)
122252884aeSStefan Eßer	h=f(r)
123252884aeSStefan Eßer	g=f(n-r)
124252884aeSStefan Eßer	f/=h*g
125252884aeSStefan Eßer	scale=s
126252884aeSStefan Eßer	return f
127252884aeSStefan Eßer}
1288c48f4c5SStefan Eßerdefine fib(n){
1298c48f4c5SStefan Eßer	auto i,t,p,r
1308c48f4c5SStefan Eßer	if(!n)return 0
1318c48f4c5SStefan Eßer	n=abs(n)$
1328c48f4c5SStefan Eßer	t=1
1338c48f4c5SStefan Eßer	for (i=1;i<n;++i){
1348c48f4c5SStefan Eßer		r=p
1358c48f4c5SStefan Eßer		p=t
1368c48f4c5SStefan Eßer		t+=r
1378c48f4c5SStefan Eßer	}
1388c48f4c5SStefan Eßer	return t
1398c48f4c5SStefan Eßer}
140252884aeSStefan Eßerdefine log(x,b){
141252884aeSStefan Eßer	auto p,s
142252884aeSStefan Eßer	s=scale
143252884aeSStefan Eßer	if(scale<K)scale=K
144252884aeSStefan Eßer	if(scale(x)>scale)scale=scale(x)
145252884aeSStefan Eßer	scale*=2
146252884aeSStefan Eßer	p=l(x)/l(b)
147252884aeSStefan Eßer	scale=s
148252884aeSStefan Eßer	return p@s
149252884aeSStefan Eßer}
150252884aeSStefan Eßerdefine l2(x){return log(x,2)}
151252884aeSStefan Eßerdefine l10(x){return log(x,A)}
152252884aeSStefan Eßerdefine root(x,n){
1538c48f4c5SStefan Eßer	auto s,t,m,r,q,p
154252884aeSStefan Eßer	if(n<0)sqrt(n)
155252884aeSStefan Eßer	n=n$
156252884aeSStefan Eßer	if(n==0)x/n
157028616d0SStefan Eßer	if(x==0||n==1)return x
158252884aeSStefan Eßer	if(n==2)return sqrt(x)
159252884aeSStefan Eßer	s=scale
160252884aeSStefan Eßer	scale=0
1618c48f4c5SStefan Eßer	if(x<0&&n%2==0){
1628c48f4c5SStefan Eßer		scale=s
1638c48f4c5SStefan Eßer		sqrt(x)
1648c48f4c5SStefan Eßer	}
1658c48f4c5SStefan Eßer	scale=s+scale(x)+5
1668c48f4c5SStefan Eßer	t=s+5
167252884aeSStefan Eßer	m=(x<0)
168252884aeSStefan Eßer	x=abs(x)
169252884aeSStefan Eßer	p=n-1
17044d4804dSStefan Eßer	q=A^ceil((length(x$)/n)$,0)
1718c48f4c5SStefan Eßer	while(r@t!=q@t){
172252884aeSStefan Eßer		r=q
173252884aeSStefan Eßer		q=(p*r+x/r^p)/n
174252884aeSStefan Eßer	}
175252884aeSStefan Eßer	if(m)r=-r
176252884aeSStefan Eßer	scale=s
177252884aeSStefan Eßer	return r@s
178252884aeSStefan Eßer}
179252884aeSStefan Eßerdefine cbrt(x){return root(x,3)}
18044d4804dSStefan Eßerdefine gcd(a,b){
18144d4804dSStefan Eßer	auto g,s
18244d4804dSStefan Eßer	if(!b)return a
18344d4804dSStefan Eßer	s=scale
18444d4804dSStefan Eßer	scale=0
18544d4804dSStefan Eßer	a=abs(a)$
18644d4804dSStefan Eßer	b=abs(b)$
18744d4804dSStefan Eßer	if(a<b){
18844d4804dSStefan Eßer		g=a
18944d4804dSStefan Eßer		a=b
19044d4804dSStefan Eßer		b=g
19144d4804dSStefan Eßer	}
19244d4804dSStefan Eßer	while(b){
19344d4804dSStefan Eßer		g=a%b
19444d4804dSStefan Eßer		a=b
19544d4804dSStefan Eßer		b=g
19644d4804dSStefan Eßer	}
19744d4804dSStefan Eßer	scale=s
19844d4804dSStefan Eßer	return a
19944d4804dSStefan Eßer}
20044d4804dSStefan Eßerdefine lcm(a,b){
20144d4804dSStefan Eßer	auto r,s
20244d4804dSStefan Eßer	if(!a&&!b)return 0
20344d4804dSStefan Eßer	s=scale
20444d4804dSStefan Eßer	scale=0
20544d4804dSStefan Eßer	a=abs(a)$
20644d4804dSStefan Eßer	b=abs(b)$
20744d4804dSStefan Eßer	r=a*b/gcd(a,b)
20844d4804dSStefan Eßer	scale=s
20944d4804dSStefan Eßer	return r
21044d4804dSStefan Eßer}
211252884aeSStefan Eßerdefine pi(s){
212252884aeSStefan Eßer	auto t,v
213252884aeSStefan Eßer	if(s==0)return 3
214252884aeSStefan Eßer	s=abs(s)$
215252884aeSStefan Eßer	t=scale
216252884aeSStefan Eßer	scale=s+1
217252884aeSStefan Eßer	v=4*a(1)
218252884aeSStefan Eßer	scale=t
219252884aeSStefan Eßer	return v@s
220252884aeSStefan Eßer}
221252884aeSStefan Eßerdefine t(x){
22244d4804dSStefan Eßer	auto s,c
223252884aeSStefan Eßer	l=scale
224252884aeSStefan Eßer	scale+=2
225252884aeSStefan Eßer	s=s(x)
226252884aeSStefan Eßer	c=c(x)
22744d4804dSStefan Eßer	scale-=2
228252884aeSStefan Eßer	return s/c
229252884aeSStefan Eßer}
230252884aeSStefan Eßerdefine a2(y,x){
231252884aeSStefan Eßer	auto a,p
232252884aeSStefan Eßer	if(!x&&!y)y/x
233252884aeSStefan Eßer	if(x<=0){
234252884aeSStefan Eßer		p=pi(scale+2)
235252884aeSStefan Eßer		if(y<0)p=-p
236252884aeSStefan Eßer	}
237252884aeSStefan Eßer	if(x==0)a=p/2
238252884aeSStefan Eßer	else{
239252884aeSStefan Eßer		scale+=2
240252884aeSStefan Eßer		a=a(y/x)+p
241252884aeSStefan Eßer		scale-=2
242252884aeSStefan Eßer	}
243252884aeSStefan Eßer	return a@scale
244252884aeSStefan Eßer}
245252884aeSStefan Eßerdefine sin(x){return s(x)}
246252884aeSStefan Eßerdefine cos(x){return c(x)}
247252884aeSStefan Eßerdefine atan(x){return a(x)}
248252884aeSStefan Eßerdefine tan(x){return t(x)}
249252884aeSStefan Eßerdefine atan2(y,x){return a2(y,x)}
250252884aeSStefan Eßerdefine r2d(x){
251252884aeSStefan Eßer	auto r,i,s
252252884aeSStefan Eßer	s=scale
253252884aeSStefan Eßer	scale+=5
254252884aeSStefan Eßer	i=ibase
255252884aeSStefan Eßer	ibase=A
256252884aeSStefan Eßer	r=x*180/pi(scale)
257252884aeSStefan Eßer	ibase=i
258252884aeSStefan Eßer	scale=s
259252884aeSStefan Eßer	return r@s
260252884aeSStefan Eßer}
261252884aeSStefan Eßerdefine d2r(x){
262252884aeSStefan Eßer	auto r,i,s
263252884aeSStefan Eßer	s=scale
264252884aeSStefan Eßer	scale+=5
265252884aeSStefan Eßer	i=ibase
266252884aeSStefan Eßer	ibase=A
267252884aeSStefan Eßer	r=x*pi(scale)/180
268252884aeSStefan Eßer	ibase=i
269252884aeSStefan Eßer	scale=s
270252884aeSStefan Eßer	return r@s
271252884aeSStefan Eßer}
272252884aeSStefan Eßerdefine frand(p){
273252884aeSStefan Eßer	p=abs(p)$
27444d4804dSStefan Eßer	return irand(A^p)>>p
275252884aeSStefan Eßer}
276252884aeSStefan Eßerdefine ifrand(i,p){return irand(abs(i)$)+frand(p)}
277aa339f1dSStefan Eßerdefine i2rand(a,b){
278aa339f1dSStefan Eßer	auto n,x
279aa339f1dSStefan Eßer	a=a$
280aa339f1dSStefan Eßer	b=b$
281aa339f1dSStefan Eßer	if(a==b)return a
282aa339f1dSStefan Eßer	n=min(a,b)
283aa339f1dSStefan Eßer	x=max(a,b)
284aa339f1dSStefan Eßer	return irand(x-n+1)+n
285aa339f1dSStefan Eßer}
286252884aeSStefan Eßerdefine srand(x){
287252884aeSStefan Eßer	if(irand(2))return -x
288252884aeSStefan Eßer	return x
289252884aeSStefan Eßer}
290252884aeSStefan Eßerdefine brand(){return irand(2)}
291252884aeSStefan Eßerdefine void output(x,b){
292252884aeSStefan Eßer	auto c
293252884aeSStefan Eßer	c=obase
294252884aeSStefan Eßer	obase=b
295252884aeSStefan Eßer	x
296252884aeSStefan Eßer	obase=c
297252884aeSStefan Eßer}
298252884aeSStefan Eßerdefine void hex(x){output(x,G)}
299252884aeSStefan Eßerdefine void binary(x){output(x,2)}
300252884aeSStefan Eßerdefine ubytes(x){
30144d4804dSStefan Eßer	auto p,i
302252884aeSStefan Eßer	x=abs(x)$
303252884aeSStefan Eßer	i=2^8
304252884aeSStefan Eßer	for(p=1;i-1<x;p*=2){i*=i}
305252884aeSStefan Eßer	return p
306252884aeSStefan Eßer}
307252884aeSStefan Eßerdefine sbytes(x){
30844d4804dSStefan Eßer	auto p,n,z
309252884aeSStefan Eßer	z=(x<0)
310d101cdd6SStefan Eßer	x=abs(x)$
311252884aeSStefan Eßer	n=ubytes(x)
312252884aeSStefan Eßer	p=2^(n*8-1)
313252884aeSStefan Eßer	if(x>p||(!z&&x==p))n*=2
314252884aeSStefan Eßer	return n
315252884aeSStefan Eßer}
31644d4804dSStefan Eßerdefine s2un(x,n){
31744d4804dSStefan Eßer	auto t,u,s
31844d4804dSStefan Eßer	x=x$
31944d4804dSStefan Eßer	if(x<0){
32044d4804dSStefan Eßer		x=abs(x)
32144d4804dSStefan Eßer		s=scale
32244d4804dSStefan Eßer		scale=0
32344d4804dSStefan Eßer		t=n*8
32444d4804dSStefan Eßer		u=2^(t-1)
32544d4804dSStefan Eßer		if(x==u)return x
32644d4804dSStefan Eßer		else if(x>u)x%=u
32744d4804dSStefan Eßer		scale=s
32844d4804dSStefan Eßer		return 2^(t)-x
32944d4804dSStefan Eßer	}
33044d4804dSStefan Eßer	return x
33144d4804dSStefan Eßer}
33244d4804dSStefan Eßerdefine s2u(x){return s2un(x,sbytes(x))}
333d43fa8efSStefan Eßerdefine void plz(x){
334d43fa8efSStefan Eßer	if(leading_zero())print x
335d43fa8efSStefan Eßer	else{
336d43fa8efSStefan Eßer		if(x>-1&&x<1&&x!=0){
337d43fa8efSStefan Eßer			if(x<0)print"-"
338d43fa8efSStefan Eßer			print 0,abs(x)
339d43fa8efSStefan Eßer		}
340d43fa8efSStefan Eßer		else print x
341d43fa8efSStefan Eßer	}
342d43fa8efSStefan Eßer}
343d43fa8efSStefan Eßerdefine void plznl(x){
344d43fa8efSStefan Eßer	plz(x)
345d43fa8efSStefan Eßer	print"\n"
346d43fa8efSStefan Eßer}
347d43fa8efSStefan Eßerdefine void pnlz(x){
348d43fa8efSStefan Eßer	auto s,i
349d43fa8efSStefan Eßer	if(leading_zero()){
350d43fa8efSStefan Eßer		if(x>-1&&x<1&&x!=0){
351d43fa8efSStefan Eßer			s=scale(x)
352d43fa8efSStefan Eßer			if(x<0)print"-"
353d43fa8efSStefan Eßer			print"."
354d43fa8efSStefan Eßer			x=abs(x)
355d43fa8efSStefan Eßer			for(i=0;i<s;++i){
356d43fa8efSStefan Eßer				x<<=1
357d43fa8efSStefan Eßer				print x$
358d43fa8efSStefan Eßer				x-=x$
359d43fa8efSStefan Eßer			}
360d43fa8efSStefan Eßer			return
361d43fa8efSStefan Eßer		}
362d43fa8efSStefan Eßer	}
363d43fa8efSStefan Eßer	print x
364d43fa8efSStefan Eßer}
365d43fa8efSStefan Eßerdefine void pnlznl(x){
366d43fa8efSStefan Eßer	pnlz(x)
367d43fa8efSStefan Eßer	print"\n"
368d43fa8efSStefan Eßer}
369252884aeSStefan Eßerdefine void output_byte(x,i){
370d101cdd6SStefan Eßer	auto j,p,y,b,s
371252884aeSStefan Eßer	s=scale
372252884aeSStefan Eßer	scale=0
373252884aeSStefan Eßer	x=abs(x)$
374252884aeSStefan Eßer	b=x/(2^(i*8))
375d101cdd6SStefan Eßer	j=2^8
376d101cdd6SStefan Eßer	b%=j
377d101cdd6SStefan Eßer	y=log(j,obase)
378252884aeSStefan Eßer	if(b>1)p=log(b,obase)+1
379252884aeSStefan Eßer	else p=b
380252884aeSStefan Eßer	for(i=y-p;i>0;--i)print 0
381252884aeSStefan Eßer	if(b)print b
382252884aeSStefan Eßer	scale=s
383252884aeSStefan Eßer}
384252884aeSStefan Eßerdefine void output_uint(x,n){
38544d4804dSStefan Eßer	auto i
386252884aeSStefan Eßer	for(i=n-1;i>=0;--i){
387252884aeSStefan Eßer		output_byte(x,i)
388252884aeSStefan Eßer		if(i)print" "
389252884aeSStefan Eßer		else print"\n"
390252884aeSStefan Eßer	}
391252884aeSStefan Eßer}
392252884aeSStefan Eßerdefine void hex_uint(x,n){
393252884aeSStefan Eßer	auto o
394252884aeSStefan Eßer	o=obase
395252884aeSStefan Eßer	obase=G
396252884aeSStefan Eßer	output_uint(x,n)
397252884aeSStefan Eßer	obase=o
398252884aeSStefan Eßer}
399252884aeSStefan Eßerdefine void binary_uint(x,n){
400252884aeSStefan Eßer	auto o
401252884aeSStefan Eßer	o=obase
402252884aeSStefan Eßer	obase=2
403252884aeSStefan Eßer	output_uint(x,n)
404252884aeSStefan Eßer	obase=o
405252884aeSStefan Eßer}
406252884aeSStefan Eßerdefine void uintn(x,n){
407252884aeSStefan Eßer	if(scale(x)){
408252884aeSStefan Eßer		print"Error: ",x," is not an integer.\n"
409252884aeSStefan Eßer		return
410252884aeSStefan Eßer	}
411252884aeSStefan Eßer	if(x<0){
412252884aeSStefan Eßer		print"Error: ",x," is negative.\n"
413252884aeSStefan Eßer		return
414252884aeSStefan Eßer	}
415252884aeSStefan Eßer	if(x>=2^(n*8)){
416252884aeSStefan Eßer		print"Error: ",x," cannot fit into ",n," unsigned byte(s).\n"
417252884aeSStefan Eßer		return
418252884aeSStefan Eßer	}
419252884aeSStefan Eßer	binary_uint(x,n)
420252884aeSStefan Eßer	hex_uint(x,n)
421252884aeSStefan Eßer}
422252884aeSStefan Eßerdefine void intn(x,n){
423252884aeSStefan Eßer	auto t
424252884aeSStefan Eßer	if(scale(x)){
425252884aeSStefan Eßer		print"Error: ",x," is not an integer.\n"
426252884aeSStefan Eßer		return
427252884aeSStefan Eßer	}
428252884aeSStefan Eßer	t=2^(n*8-1)
429252884aeSStefan Eßer	if(abs(x)>=t&&(x>0||x!=-t)){
430252884aeSStefan Eßer		print "Error: ",x," cannot fit into ",n," signed byte(s).\n"
431252884aeSStefan Eßer		return
432252884aeSStefan Eßer	}
43344d4804dSStefan Eßer	x=s2un(x,n)
434252884aeSStefan Eßer	binary_uint(x,n)
435252884aeSStefan Eßer	hex_uint(x,n)
436252884aeSStefan Eßer}
437252884aeSStefan Eßerdefine void uint8(x){uintn(x,1)}
438252884aeSStefan Eßerdefine void int8(x){intn(x,1)}
439252884aeSStefan Eßerdefine void uint16(x){uintn(x,2)}
440252884aeSStefan Eßerdefine void int16(x){intn(x,2)}
441252884aeSStefan Eßerdefine void uint32(x){uintn(x,4)}
442252884aeSStefan Eßerdefine void int32(x){intn(x,4)}
443252884aeSStefan Eßerdefine void uint64(x){uintn(x,8)}
444252884aeSStefan Eßerdefine void int64(x){intn(x,8)}
445252884aeSStefan Eßerdefine void uint(x){uintn(x,ubytes(x))}
446252884aeSStefan Eßerdefine void int(x){intn(x,sbytes(x))}
44744d4804dSStefan Eßerdefine bunrev(t){
44844d4804dSStefan Eßer	auto a,s,m[]
44944d4804dSStefan Eßer	s=scale
45044d4804dSStefan Eßer	scale=0
45144d4804dSStefan Eßer	t=abs(t)$
45244d4804dSStefan Eßer	while(t!=1){
45344d4804dSStefan Eßer		t=divmod(t,2,m[])
45444d4804dSStefan Eßer		a*=2
45544d4804dSStefan Eßer		a+=m[0]
45644d4804dSStefan Eßer	}
45744d4804dSStefan Eßer	scale=s
45844d4804dSStefan Eßer	return a
45944d4804dSStefan Eßer}
46044d4804dSStefan Eßerdefine band(a,b){
46144d4804dSStefan Eßer	auto s,t,m[],n[]
46244d4804dSStefan Eßer	a=abs(a)$
46344d4804dSStefan Eßer	b=abs(b)$
46444d4804dSStefan Eßer	if(b>a){
46544d4804dSStefan Eßer		t=b
46644d4804dSStefan Eßer		b=a
46744d4804dSStefan Eßer		a=t
46844d4804dSStefan Eßer	}
46944d4804dSStefan Eßer	s=scale
47044d4804dSStefan Eßer	scale=0
47144d4804dSStefan Eßer	t=1
47244d4804dSStefan Eßer	while(b){
47344d4804dSStefan Eßer		a=divmod(a,2,m[])
47444d4804dSStefan Eßer		b=divmod(b,2,n[])
47544d4804dSStefan Eßer		t*=2
47644d4804dSStefan Eßer		t+=(m[0]&&n[0])
47744d4804dSStefan Eßer	}
47844d4804dSStefan Eßer	scale=s
47944d4804dSStefan Eßer	return bunrev(t)
48044d4804dSStefan Eßer}
48144d4804dSStefan Eßerdefine bor(a,b){
48244d4804dSStefan Eßer	auto s,t,m[],n[]
48344d4804dSStefan Eßer	a=abs(a)$
48444d4804dSStefan Eßer	b=abs(b)$
48544d4804dSStefan Eßer	if(b>a){
48644d4804dSStefan Eßer		t=b
48744d4804dSStefan Eßer		b=a
48844d4804dSStefan Eßer		a=t
48944d4804dSStefan Eßer	}
49044d4804dSStefan Eßer	s=scale
49144d4804dSStefan Eßer	scale=0
49244d4804dSStefan Eßer	t=1
49344d4804dSStefan Eßer	while(b){
49444d4804dSStefan Eßer		a=divmod(a,2,m[])
49544d4804dSStefan Eßer		b=divmod(b,2,n[])
49644d4804dSStefan Eßer		t*=2
49744d4804dSStefan Eßer		t+=(m[0]||n[0])
49844d4804dSStefan Eßer	}
49944d4804dSStefan Eßer	while(a){
50044d4804dSStefan Eßer		a=divmod(a,2,m[])
50144d4804dSStefan Eßer		t*=2
50244d4804dSStefan Eßer		t+=m[0]
50344d4804dSStefan Eßer	}
50444d4804dSStefan Eßer	scale=s
50544d4804dSStefan Eßer	return bunrev(t)
50644d4804dSStefan Eßer}
50744d4804dSStefan Eßerdefine bxor(a,b){
50844d4804dSStefan Eßer	auto s,t,m[],n[]
50944d4804dSStefan Eßer	a=abs(a)$
51044d4804dSStefan Eßer	b=abs(b)$
51144d4804dSStefan Eßer	if(b>a){
51244d4804dSStefan Eßer		t=b
51344d4804dSStefan Eßer		b=a
51444d4804dSStefan Eßer		a=t
51544d4804dSStefan Eßer	}
51644d4804dSStefan Eßer	s=scale
51744d4804dSStefan Eßer	scale=0
51844d4804dSStefan Eßer	t=1
51944d4804dSStefan Eßer	while(b){
52044d4804dSStefan Eßer		a=divmod(a,2,m[])
52144d4804dSStefan Eßer		b=divmod(b,2,n[])
52244d4804dSStefan Eßer		t*=2
52344d4804dSStefan Eßer		t+=(m[0]+n[0]==1)
52444d4804dSStefan Eßer	}
52544d4804dSStefan Eßer	while(a){
52644d4804dSStefan Eßer		a=divmod(a,2,m[])
52744d4804dSStefan Eßer		t*=2
52844d4804dSStefan Eßer		t+=m[0]
52944d4804dSStefan Eßer	}
53044d4804dSStefan Eßer	scale=s
53144d4804dSStefan Eßer	return bunrev(t)
53244d4804dSStefan Eßer}
53344d4804dSStefan Eßerdefine bshl(a,b){return abs(a)$*2^abs(b)$}
53444d4804dSStefan Eßerdefine bshr(a,b){return(abs(a)$/2^abs(b)$)$}
53544d4804dSStefan Eßerdefine bnotn(x,n){
53644d4804dSStefan Eßer	auto s,t,m[]
53744d4804dSStefan Eßer	s=scale
53844d4804dSStefan Eßer	scale=0
53944d4804dSStefan Eßer	t=2^(abs(n)$*8)
54044d4804dSStefan Eßer	x=abs(x)$%t+t
54144d4804dSStefan Eßer	t=1
54244d4804dSStefan Eßer	while(x!=1){
54344d4804dSStefan Eßer		x=divmod(x,2,m[])
54444d4804dSStefan Eßer		t*=2
54544d4804dSStefan Eßer		t+=!m[0]
54644d4804dSStefan Eßer	}
54744d4804dSStefan Eßer	scale=s
54844d4804dSStefan Eßer	return bunrev(t)
54944d4804dSStefan Eßer}
55044d4804dSStefan Eßerdefine bnot8(x){return bnotn(x,1)}
55144d4804dSStefan Eßerdefine bnot16(x){return bnotn(x,2)}
55244d4804dSStefan Eßerdefine bnot32(x){return bnotn(x,4)}
55344d4804dSStefan Eßerdefine bnot64(x){return bnotn(x,8)}
55444d4804dSStefan Eßerdefine bnot(x){return bnotn(x,ubytes(x))}
55544d4804dSStefan Eßerdefine brevn(x,n){
55644d4804dSStefan Eßer	auto s,t,m[]
55744d4804dSStefan Eßer	s=scale
55844d4804dSStefan Eßer	scale=0
55944d4804dSStefan Eßer	t=2^(abs(n)$*8)
56044d4804dSStefan Eßer	x=abs(x)$%t+t
56144d4804dSStefan Eßer	scale=s
56244d4804dSStefan Eßer	return bunrev(x)
56344d4804dSStefan Eßer}
56444d4804dSStefan Eßerdefine brev8(x){return brevn(x,1)}
56544d4804dSStefan Eßerdefine brev16(x){return brevn(x,2)}
56644d4804dSStefan Eßerdefine brev32(x){return brevn(x,4)}
56744d4804dSStefan Eßerdefine brev64(x){return brevn(x,8)}
56844d4804dSStefan Eßerdefine brev(x){return brevn(x,ubytes(x))}
56944d4804dSStefan Eßerdefine broln(x,p,n){
57044d4804dSStefan Eßer	auto s,t,m[]
57144d4804dSStefan Eßer	s=scale
57244d4804dSStefan Eßer	scale=0
57344d4804dSStefan Eßer	n=abs(n)$*8
57444d4804dSStefan Eßer	p=abs(p)$%n
57544d4804dSStefan Eßer	t=2^n
57644d4804dSStefan Eßer	x=abs(x)$%t
57744d4804dSStefan Eßer	if(!p)return x
57844d4804dSStefan Eßer	x=divmod(x,2^(n-p),m[])
57944d4804dSStefan Eßer	x+=m[0]*2^p%t
58044d4804dSStefan Eßer	scale=s
58144d4804dSStefan Eßer	return x
58244d4804dSStefan Eßer}
58344d4804dSStefan Eßerdefine brol8(x,p){return broln(x,p,1)}
58444d4804dSStefan Eßerdefine brol16(x,p){return broln(x,p,2)}
58544d4804dSStefan Eßerdefine brol32(x,p){return broln(x,p,4)}
58644d4804dSStefan Eßerdefine brol64(x,p){return broln(x,p,8)}
58744d4804dSStefan Eßerdefine brol(x,p){return broln(x,p,ubytes(x))}
58844d4804dSStefan Eßerdefine brorn(x,p,n){
58944d4804dSStefan Eßer	auto s,t,m[]
59044d4804dSStefan Eßer	s=scale
59144d4804dSStefan Eßer	scale=0
59244d4804dSStefan Eßer	n=abs(n)$*8
59344d4804dSStefan Eßer	p=abs(p)$%n
59444d4804dSStefan Eßer	t=2^n
59544d4804dSStefan Eßer	x=abs(x)$%t
59644d4804dSStefan Eßer	if(!p)return x
59744d4804dSStefan Eßer	x=divmod(x,2^p,m[])
59844d4804dSStefan Eßer	x+=m[0]*2^(n-p)%t
59944d4804dSStefan Eßer	scale=s
60044d4804dSStefan Eßer	return x
60144d4804dSStefan Eßer}
60244d4804dSStefan Eßerdefine bror8(x,p){return brorn(x,p,1)}
60344d4804dSStefan Eßerdefine bror16(x,p){return brorn(x,p,2)}
60444d4804dSStefan Eßerdefine bror32(x,p){return brorn(x,p,4)}
60544d4804dSStefan Eßerdefine bror64(x,p){return brorn(x,p,8)}
60644d4804dSStefan Eßerdefine brol(x,p){return brorn(x,p,ubytes(x))}
60744d4804dSStefan Eßerdefine bmodn(x,n){
60844d4804dSStefan Eßer	auto s
60944d4804dSStefan Eßer	s=scale
61044d4804dSStefan Eßer	scale=0
61144d4804dSStefan Eßer	x=abs(x)$%2^(abs(n)$*8)
61244d4804dSStefan Eßer	scale=s
61344d4804dSStefan Eßer	return x
61444d4804dSStefan Eßer}
61544d4804dSStefan Eßerdefine bmod8(x){return bmodn(x,1)}
61644d4804dSStefan Eßerdefine bmod16(x){return bmodn(x,2)}
61744d4804dSStefan Eßerdefine bmod32(x){return bmodn(x,4)}
61844d4804dSStefan Eßerdefine bmod64(x){return bmodn(x,8)}
619