1f4fbc49dSStefan Eßer#! /usr/bin/bc 2f4fbc49dSStefan Eßer# 3f4fbc49dSStefan Eßer# SPDX-License-Identifier: BSD-2-Clause 4f4fbc49dSStefan Eßer# 5*a970610aSStefan Eßer# Copyright (c) 2018-2024 Gavin D. Howard and contributors. 6f4fbc49dSStefan Eßer# 7f4fbc49dSStefan Eßer# Redistribution and use in source and binary forms, with or without 8f4fbc49dSStefan Eßer# modification, are permitted provided that the following conditions are met: 9f4fbc49dSStefan Eßer# 10f4fbc49dSStefan Eßer# * Redistributions of source code must retain the above copyright notice, this 11f4fbc49dSStefan Eßer# list of conditions and the following disclaimer. 12f4fbc49dSStefan Eßer# 13f4fbc49dSStefan Eßer# * Redistributions in binary form must reproduce the above copyright notice, 14f4fbc49dSStefan Eßer# this list of conditions and the following disclaimer in the documentation 15f4fbc49dSStefan Eßer# and/or other materials provided with the distribution. 16f4fbc49dSStefan Eßer# 17f4fbc49dSStefan Eßer# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18f4fbc49dSStefan Eßer# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19f4fbc49dSStefan Eßer# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20f4fbc49dSStefan Eßer# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21f4fbc49dSStefan Eßer# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22f4fbc49dSStefan Eßer# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23f4fbc49dSStefan Eßer# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24f4fbc49dSStefan Eßer# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25f4fbc49dSStefan Eßer# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26f4fbc49dSStefan Eßer# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27f4fbc49dSStefan Eßer# POSSIBILITY OF SUCH DAMAGE. 28f4fbc49dSStefan Eßer# 29f4fbc49dSStefan Eßer 30f4fbc49dSStefan Eßerscale = 20 31f4fbc49dSStefan Eßer 32f4fbc49dSStefan Eßer# Adjust this number to try ranges below different powers of 10. 33f4fbc49dSStefan Eßershift = 4 34f4fbc49dSStefan Eßer 35f4fbc49dSStefan Eßer# Adjust this to try extra digits. For example, a value of one means that one 36f4fbc49dSStefan Eßer# digit is checked (such as 0.09 through 0.01), a value of two means that two 37f4fbc49dSStefan Eßer# digits are checked (0.090 through 0.010), etc. 38f4fbc49dSStefan Eßermax = shift + 2 39f4fbc49dSStefan Eßer 40f4fbc49dSStefan Eßern = (9 >> shift) 41f4fbc49dSStefan Eßerinc = (1 >> max) 42f4fbc49dSStefan Eßerstop = (1 >> shift) 43f4fbc49dSStefan Eßer 44f4fbc49dSStefan Eßer# Uncomment this to test the high part of the ranges. 45f4fbc49dSStefan Eßer#n += (1 - (1 >> max + 5)) >> shift 46f4fbc49dSStefan Eßer 47f4fbc49dSStefan Eßerfor (i = n; i >= stop; i -= inc) 48f4fbc49dSStefan Eßer{ 49f4fbc49dSStefan Eßer # This is the lower limit. 50f4fbc49dSStefan Eßer t1 = sqrt(1/(3*i)) 51f4fbc49dSStefan Eßer 52f4fbc49dSStefan Eßer # Start with the inverse. 53f4fbc49dSStefan Eßer t2 = (1/i) 54f4fbc49dSStefan Eßer 55f4fbc49dSStefan Eßer # And take half its length of course. 56f4fbc49dSStefan Eßer l = length(t2$)/2 57f4fbc49dSStefan Eßer 58f4fbc49dSStefan Eßer temp = i 59f4fbc49dSStefan Eßer odd = 0 60f4fbc49dSStefan Eßer 61f4fbc49dSStefan Eßer # We go by powers of 10 below, but there is a degenerate case: an exact 62f4fbc49dSStefan Eßer # power of 10, for which length() will return one digit more. So we check 63f4fbc49dSStefan Eßer # for that and fix it. 64f4fbc49dSStefan Eßer while (temp < 1) 65f4fbc49dSStefan Eßer { 66f4fbc49dSStefan Eßer temp <<= 1 67f4fbc49dSStefan Eßer odd = !odd 68f4fbc49dSStefan Eßer } 69f4fbc49dSStefan Eßer 70f4fbc49dSStefan Eßer if (temp == 1) 71f4fbc49dSStefan Eßer { 72f4fbc49dSStefan Eßer odd = !odd 73f4fbc49dSStefan Eßer } 74f4fbc49dSStefan Eßer 75f4fbc49dSStefan Eßer print "i: ", i, "\n" 76f4fbc49dSStefan Eßer print "t2: ", t2, "\n" 77f4fbc49dSStefan Eßer #print "l: ", l, "\n" 78f4fbc49dSStefan Eßer print "odd: ", odd, "\n" 79f4fbc49dSStefan Eßer 80f4fbc49dSStefan Eßer if (odd) 81f4fbc49dSStefan Eßer { 82f4fbc49dSStefan Eßer # Limit between 6 and 7.5. 83f4fbc49dSStefan Eßer limit1 = 6.7 >> (l$ * 2 + 1) 84f4fbc49dSStefan Eßer 85f4fbc49dSStefan Eßer # Limit between 1.5 and 1.83-ish. 86f4fbc49dSStefan Eßer limit2 = 1.7 >> (l$ * 2 + 1) 87f4fbc49dSStefan Eßer print "limit1: ", limit1, "\n" 88f4fbc49dSStefan Eßer print "limit2: ", limit2, "\n" 89f4fbc49dSStefan Eßer 90f4fbc49dSStefan Eßer if (i >= limit1) 91f4fbc49dSStefan Eßer { 92f4fbc49dSStefan Eßer t2 = (t2 >> l$) 93f4fbc49dSStefan Eßer } 94f4fbc49dSStefan Eßer else if (i >= limit2) 95f4fbc49dSStefan Eßer { 96f4fbc49dSStefan Eßer t2 = (t2 >> l$) / 2 97f4fbc49dSStefan Eßer } 98f4fbc49dSStefan Eßer else 99f4fbc49dSStefan Eßer { 100f4fbc49dSStefan Eßer t2 = (t2 >> l$) / 4 101f4fbc49dSStefan Eßer } 102f4fbc49dSStefan Eßer } 103f4fbc49dSStefan Eßer else 104f4fbc49dSStefan Eßer { 105f4fbc49dSStefan Eßer # Limit between 2.4 and 3. 106f4fbc49dSStefan Eßer limit = 2.7 >> (l$ * 2) 107f4fbc49dSStefan Eßer print "limit: ", limit, "\n" 108f4fbc49dSStefan Eßer 109f4fbc49dSStefan Eßer if (i >= limit) 110f4fbc49dSStefan Eßer { 111f4fbc49dSStefan Eßer t2 = (t2 >> l$) * 2 112f4fbc49dSStefan Eßer } 113f4fbc49dSStefan Eßer else 114f4fbc49dSStefan Eßer { 115f4fbc49dSStefan Eßer t2 = (t2 >> l$) 116f4fbc49dSStefan Eßer } 117f4fbc49dSStefan Eßer } 118f4fbc49dSStefan Eßer #t2 = 1 119f4fbc49dSStefan Eßer t3 = sqrt(5/(3*i)) 120f4fbc49dSStefan Eßer good = (t1 < t2 && t2 < t3) 121f4fbc49dSStefan Eßer 122f4fbc49dSStefan Eßer print t1, " < ", t2, " < ", t3, ": ", good, "\n\n" 123f4fbc49dSStefan Eßer if (!good) sqrt(-1) 124f4fbc49dSStefan Eßer} 125f4fbc49dSStefan Eßer 126f4fbc49dSStefan Eßerhalt 127