xref: /aosp_15_r20/external/bc/scripts/sqrt_random.bc (revision 5a6e848804d15c18a0125914844ee4eb0bda4fcf)
1*5a6e8488SAndroid Build Coastguard Worker#! /usr/bin/bc
2*5a6e8488SAndroid Build Coastguard Worker#
3*5a6e8488SAndroid Build Coastguard Worker# SPDX-License-Identifier: BSD-2-Clause
4*5a6e8488SAndroid Build Coastguard Worker#
5*5a6e8488SAndroid Build Coastguard Worker# Copyright (c) 2018-2024 Gavin D. Howard and contributors.
6*5a6e8488SAndroid Build Coastguard Worker#
7*5a6e8488SAndroid Build Coastguard Worker# Redistribution and use in source and binary forms, with or without
8*5a6e8488SAndroid Build Coastguard Worker# modification, are permitted provided that the following conditions are met:
9*5a6e8488SAndroid Build Coastguard Worker#
10*5a6e8488SAndroid Build Coastguard Worker# * Redistributions of source code must retain the above copyright notice, this
11*5a6e8488SAndroid Build Coastguard Worker#   list of conditions and the following disclaimer.
12*5a6e8488SAndroid Build Coastguard Worker#
13*5a6e8488SAndroid Build Coastguard Worker# * Redistributions in binary form must reproduce the above copyright notice,
14*5a6e8488SAndroid Build Coastguard Worker#   this list of conditions and the following disclaimer in the documentation
15*5a6e8488SAndroid Build Coastguard Worker#   and/or other materials provided with the distribution.
16*5a6e8488SAndroid Build Coastguard Worker#
17*5a6e8488SAndroid Build Coastguard Worker# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18*5a6e8488SAndroid Build Coastguard Worker# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19*5a6e8488SAndroid Build Coastguard Worker# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20*5a6e8488SAndroid Build Coastguard Worker# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21*5a6e8488SAndroid Build Coastguard Worker# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22*5a6e8488SAndroid Build Coastguard Worker# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23*5a6e8488SAndroid Build Coastguard Worker# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24*5a6e8488SAndroid Build Coastguard Worker# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25*5a6e8488SAndroid Build Coastguard Worker# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26*5a6e8488SAndroid Build Coastguard Worker# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27*5a6e8488SAndroid Build Coastguard Worker# POSSIBILITY OF SUCH DAMAGE.
28*5a6e8488SAndroid Build Coastguard Worker#
29*5a6e8488SAndroid Build Coastguard Worker
30*5a6e8488SAndroid Build Coastguard Workerscale = 0
31*5a6e8488SAndroid Build Coastguard Worker
32*5a6e8488SAndroid Build Coastguard Workerbits = rand()
33*5a6e8488SAndroid Build Coastguard Worker
34*5a6e8488SAndroid Build Coastguard Worker# This extracts a bit and takes it out of the original value.
35*5a6e8488SAndroid Build Coastguard Worker#
36*5a6e8488SAndroid Build Coastguard Worker# Here, I am getting a bit to say whether we should have a value that is less
37*5a6e8488SAndroid Build Coastguard Worker# than 1.
38*5a6e8488SAndroid Build Coastguard Workerbits = divmod(bits, 2, negpow[])
39*5a6e8488SAndroid Build Coastguard Worker
40*5a6e8488SAndroid Build Coastguard Worker# Get a bit that will say whether the value should be an exact square.
41*5a6e8488SAndroid Build Coastguard Workerbits = divmod(bits, 2, square[])
42*5a6e8488SAndroid Build Coastguard Worker
43*5a6e8488SAndroid Build Coastguard Worker# See below. This is to help bias toward small numbers.
44*5a6e8488SAndroid Build Coastguard Workerpow = 4
45*5a6e8488SAndroid Build Coastguard Worker
46*5a6e8488SAndroid Build Coastguard Worker# I want to bias toward small numbers, so let's give a 50 percent chance to
47*5a6e8488SAndroid Build Coastguard Worker# values below 16 or so.
48*5a6e8488SAndroid Build Coastguard Workerbits = divmod(bits, 2, small[])
49*5a6e8488SAndroid Build Coastguard Worker
50*5a6e8488SAndroid Build Coastguard Worker# Let's keep raising the power limit by 2^4 when the bit is zero.
51*5a6e8488SAndroid Build Coastguard Workerwhile (!small[0])
52*5a6e8488SAndroid Build Coastguard Worker{
53*5a6e8488SAndroid Build Coastguard Worker	pow += 4
54*5a6e8488SAndroid Build Coastguard Worker	bits = divmod(bits, 2, small[])
55*5a6e8488SAndroid Build Coastguard Worker}
56*5a6e8488SAndroid Build Coastguard Worker
57*5a6e8488SAndroid Build Coastguard Workerlimit = 2^pow
58*5a6e8488SAndroid Build Coastguard Worker
59*5a6e8488SAndroid Build Coastguard Worker# Okay, this is the starting number.
60*5a6e8488SAndroid Build Coastguard Workernum = irand(limit) + 1
61*5a6e8488SAndroid Build Coastguard Worker
62*5a6e8488SAndroid Build Coastguard Worker# Figure out if we should have (more) fractional digits.
63*5a6e8488SAndroid Build Coastguard Workerbits = divmod(bits, 2, extra_digits[])
64*5a6e8488SAndroid Build Coastguard Worker
65*5a6e8488SAndroid Build Coastguard Workerif (square[0])
66*5a6e8488SAndroid Build Coastguard Worker{
67*5a6e8488SAndroid Build Coastguard Worker	# Okay, I lied. If we need a perfect square, square now.
68*5a6e8488SAndroid Build Coastguard Worker	num *= num
69*5a6e8488SAndroid Build Coastguard Worker
70*5a6e8488SAndroid Build Coastguard Worker	# If we need extra digits, we need to multiply by an even power of 10.
71*5a6e8488SAndroid Build Coastguard Worker	if (extra_digits[0])
72*5a6e8488SAndroid Build Coastguard Worker	{
73*5a6e8488SAndroid Build Coastguard Worker		extra = (irand(8) + 1) * 2
74*5a6e8488SAndroid Build Coastguard Worker	}
75*5a6e8488SAndroid Build Coastguard Worker	else
76*5a6e8488SAndroid Build Coastguard Worker	{
77*5a6e8488SAndroid Build Coastguard Worker		extra = 0
78*5a6e8488SAndroid Build Coastguard Worker	}
79*5a6e8488SAndroid Build Coastguard Worker
80*5a6e8488SAndroid Build Coastguard Worker	# If we need a number less than 1, just take the inverse, which will still
81*5a6e8488SAndroid Build Coastguard Worker	# be a perfect square.
82*5a6e8488SAndroid Build Coastguard Worker	if (negpow[0])
83*5a6e8488SAndroid Build Coastguard Worker	{
84*5a6e8488SAndroid Build Coastguard Worker		scale = length(num) + 5
85*5a6e8488SAndroid Build Coastguard Worker		num = 1/num
86*5a6e8488SAndroid Build Coastguard Worker		scale = 0
87*5a6e8488SAndroid Build Coastguard Worker
88*5a6e8488SAndroid Build Coastguard Worker		num >>= extra
89*5a6e8488SAndroid Build Coastguard Worker	}
90*5a6e8488SAndroid Build Coastguard Worker	else
91*5a6e8488SAndroid Build Coastguard Worker	{
92*5a6e8488SAndroid Build Coastguard Worker		num <<= extra
93*5a6e8488SAndroid Build Coastguard Worker	}
94*5a6e8488SAndroid Build Coastguard Worker}
95*5a6e8488SAndroid Build Coastguard Workerelse
96*5a6e8488SAndroid Build Coastguard Worker{
97*5a6e8488SAndroid Build Coastguard Worker	# Get this for later.
98*5a6e8488SAndroid Build Coastguard Worker	l = length(num)
99*5a6e8488SAndroid Build Coastguard Worker
100*5a6e8488SAndroid Build Coastguard Worker	# If we need extra digits.
101*5a6e8488SAndroid Build Coastguard Worker	if (extra_digits[0])
102*5a6e8488SAndroid Build Coastguard Worker	{
103*5a6e8488SAndroid Build Coastguard Worker		# Add up to 32 decimal places.
104*5a6e8488SAndroid Build Coastguard Worker		num += frand(irand(32) + 1)
105*5a6e8488SAndroid Build Coastguard Worker	}
106*5a6e8488SAndroid Build Coastguard Worker
107*5a6e8488SAndroid Build Coastguard Worker	# If we need a value less than 1...
108*5a6e8488SAndroid Build Coastguard Worker	if (negpow[0])
109*5a6e8488SAndroid Build Coastguard Worker	{
110*5a6e8488SAndroid Build Coastguard Worker		# Move right until the number is
111*5a6e8488SAndroid Build Coastguard Worker		num >>= l
112*5a6e8488SAndroid Build Coastguard Worker	}
113*5a6e8488SAndroid Build Coastguard Worker}
114*5a6e8488SAndroid Build Coastguard Worker
115*5a6e8488SAndroid Build Coastguard Workerbits = divmod(bits, 2, zero_scale[])
116*5a6e8488SAndroid Build Coastguard Worker
117*5a6e8488SAndroid Build Coastguard Worker# Do we want a zero scale?
118*5a6e8488SAndroid Build Coastguard Workerif (zero_scale[0])
119*5a6e8488SAndroid Build Coastguard Worker{
120*5a6e8488SAndroid Build Coastguard Worker	print "scale = 0\n"
121*5a6e8488SAndroid Build Coastguard Worker}
122*5a6e8488SAndroid Build Coastguard Workerelse
123*5a6e8488SAndroid Build Coastguard Worker{
124*5a6e8488SAndroid Build Coastguard Worker	print "scale = 20\n"
125*5a6e8488SAndroid Build Coastguard Worker}
126*5a6e8488SAndroid Build Coastguard Worker
127*5a6e8488SAndroid Build Coastguard Workerprint "sqrt(", num, ")\n"
128*5a6e8488SAndroid Build Coastguard Worker
129*5a6e8488SAndroid Build Coastguard Workerhalt
130