Overflow in SML: Exponentiation procedure - overflow

I'm trying to write a simple procedure that calculates x to the power of 17 in the language Standard ML. I'm supposed to do it with a "helping procedure":
fun help (y:int) = y * y * y * y;
fun power17 (x:int) = help (help (help (help (x) ) ) ) * x;
This causes an overflow. Can somebody tell me why it does so?

You are getting an Integer Overflow. If you want your code to work, you need to use LargeInt.int.
fun help (y: LargeInt.int) = y * y * y * y;
fun power17 (x: int) =
let
val x' = Int.toLarge x
in
help (help (help (help (x')))) * x'
end;
One more thing, that code is not calculating x ** 17, instead it's doing x ** 257.
You should only call help twice:
fun power17 (x:int) = (help (help x)) * x;

Your function does not calculate the power of 17. Evaluating it:
power17 2 ~> help (help (help (help x))) * 2
~> help (help (help (2 * 2 * 2 * 2))) * 2 (* that's 2^5 *)
~> help (help (help (8))) * 2
~> help (help (8 * 8 * 8 * 8)) * 2 (* that's 2^13 *)
~> help (help (4096)) * 2
~> help (4096 * 4096 * 4096 * 4096) * 2 (* that's 2^49 *)
~> raise Overflow (* most SML compilers have 32-bit ints *)
Perhaps you meant to write:
fun power17 x = help x * help x * help x * help x * x
It sounds like an ideal case for recursion, though:
fun power (x, 0) = 1
| power (x, n) = x * power (x, n-1)
fun power17 x = power (x, 17)

Related

Exponentiation - positional system based on three

I have a natural number x in the decimal system and natural number n in a ternary numeral system. How to calculate the value of x^n using the minimum number of multiplications?
I know the algorithm for a binary system and I was looking for an analogy, but I did not find it.
Perhaps you need something like this:
function expbycubing(x, n):
//treat n = 0..2 cases here
switch n % 3:
0: return expbycubing(x * x * x, n shrt 1)
///// note shift in ternary system (tri)201 => (tri)020
1: return x * expbycubing(x * x * x, n shrt 1)
2: return x * x * expbycubing(x * x * x, n shrt 1)
Working Delphi code
function expbycubing(x, n: Integer): int64;
begin
Memo1.Lines.Add(Format('x: %d n: %d', [x, n]));
if n = 0 then Exit(1);
if n = 1 then Exit(x);
if n = 2 then Exit(x * x);
case n mod 3 of
0: Result := expbycubing(x * x * x, n div 3);
1: Result := x * expbycubing(x * x * x, n div 3);
2: Result := x * x * expbycubing(x * x * x, n div 3);
end;
end;
var
i: Integer;
begin
for i := 12 to 12 do
Memo1.Lines.Add(Format('%d: %d', [i, expbycubing(2, i)]));
end;
log:
x: 2 n: 12
x: 8 n: 4
x: 512 n: 1
12: 4096

difficult in understanding some logic circuits

Finding it difficult to get the logic expression for this circuit? Help will be appreciated
enter image description here
Here is a detailed solution, I hope (i) that the steps are clear, and (ii) that my calculation is correct :-)
The circuit has four logical gates: an AND gate with output X = B*C (short for B AND C), a NOT gate which inverts the value of A yielding A' (short for NOT A), a NOR gate with inputs A' and X and output Y = (A' + X)' (short for NOT ((NOT A) OR X))) and a final AND gate with inputs Y, A and B and output Z = A*B*Y (short for Z = A AND B AND Y). The expression for Z is then:
Z = A * B * Y = A * B * ( (A' + X)' ) = A * B * { [A' + (B*C)]' }
Repeatedly applying DeMorgan laws to the expression in the brackets yields:
[A' + (B*C)]' = A'' * (B*C)' = A *(B' + C')
So
Z = A * B * [ A *(B' + C') ] = A * B * A * (B' + C')
Since A*B*A = A*A*B = (A*A)*B and A*A = A this yields
Z = A * B * (B' + C') = A * B * B' + A * B * C'
And finally, since B * B' = 0, X * 0 = 0:
Z = 0 + A * B * C' = A * B * C' = A AND B AND (NOT C)

How to pick a number based on probability?

I want to select a random number from 0,1,2,3...n, however I want to make it that the chance of selecting k|0<k<n will be lower by multiplication of x from selecting k - 1 so x = (k - 1) / k. As bigger the number as smaller the chances to pick it up.
As an answer I want to see the implementation of the next method:
int pickANumber(n,x)
This is for a game that I am developing, I saw those questions as related but not exactly that same:
How to pick an item by its probability
C Function for picking from a list where each element has a distinct probabili
p1 + p2 + ... + pn = 1
p1 = p2 * x
p2 = p3 * x
...
p_n-1 = pn * x
Solving this gives you:
p1 + p2 + ... + pn = 1
(p2 * x) + (p3 * x) + ... + (pn * x) + pn = 1
((p3*x) * x) + ((p4*x) * x) + ... + ((p_n-1*x) * x) + pn = 1
....
pn* (x^(n-1) + x^(n-2) + ... +x^1 + x^0) = 1
pn*(1-x^n)/(1-x) = 1
pn = (1-x)/(1-x^n)
This gives you the probability you need to set to pn, and from it you can calculate the probabilities for all other p1,p2,...p_n-1
Now, you can use a "black box" RNG that chooses a number with a distribution, like those in the threads you mentioned.
A simple approach to do it is to set an auxillary array:
aux[i] = p1 + p2 + ... + pi
Now, draw a random number with uniform distribution between 0 to aux[n], and using binary search (aux array is sorted), get the first value, which matching value in aux is greater than the random uniform number you got
Original answer, for substraction (before question was editted):
For n items, you need to solve the equation:
p1 + p2 + ... + pn = 1
p1 = p2 + x
p2 = p3 + x
...
p_n-1 = pn + x
Solving this gives you:
p1 + p2 + ... + pn = 1
(p2 + x) + (p3 + x) + ... + (pn + x) + pn = 1
((p3+x) + x) + ((p4+x) + x) + ... + ((p_n-1+x) + x) + pn = 1
....
pn* ((n-1)x + (n-2)x + ... +x + 0) = 1
pn* x = n(n-1)/2
pn = n(n-1)/(2x)
This gives you the probability you need to set to pn, and from it you can calculate the probabilities for all other p1,p2,...p_n-1
Now, you can use a "black box" RNG that chooses a number with a distribution, like those in the threads you mentioned.
Be advised, this is not guaranteed you will have a solution such that 0<p_i<1 for all i, but you cannot guarantee one given from your requirements, and it is going to depend on values of n and x to fit.
Edit This answer was for the OPs original question, which was different in that each probability was supposed to be lower by a fixed amount than the previous one.
Well, let's see what the constraints say. You want to have P(k) = P(k - 1) - x. So we have:
P(0)
P(1) = P(0) - x
P(2) = P(0) - 2x
...
In addition, Sumk P(k) = 1. Summing, we get:
1 = (n + 1)P(0) -x * n / 2 (n + 1),
This gives you an easy constraint between x and P(0). Solve for one in terms of the other.
For this I would use the Mersenne Twister algorithm for a uniform distribution which Boost provides, then have a mapping function to map the results of that random distribution to the actual number select.
Here's a quick example of a potential implementation, although I left out the quadtratic equation implementation since it is well known:
int f_of_xib(int x, int i, int b)
{
return x * i * i / 2 + b * i;
}
int b_of_x(int i, int x)
{
return (r - ( r ) / 2 );
}
int pickANumber(mt19937 gen, int n, int x)
{
// First, determine the range r required where the probability equals i * x
// since probability of each increasing integer is x higher of occuring.
// Let f(i) = r and given f'(i) = x * i then r = ( x * i ^2 ) / 2 + b * i
// where b = ( r - ( x * i ^ 2 ) / 2 ) / i . Since r = x when i = 1 from problem
// definition, this reduces down to b = r - r / 2. therefore to find r_max simply
// plugin x to find b, then plugin n for i, x, and b to get r_max since r_max occurs
// when n == i.
// Find b when
int b = b_of_x(x);
int r_max = f_of_xib(x, n, b);
boost::uniform_int<> range(0, r_max);
boost::variate_generator<boost::mt19937&, boost::uniform_int<> > next(gen, range);
// Now to map random number to desired number, just find the positive value for i
// when r is the return random number which boils down to finding the non-zero root
// when 0 = ( x * i ^ 2 ) / 2 + b * i - r
int random_number = next();
return quadtratic_equation_for_positive_value(1, b, r);
}
int main(int argc, char** argv)
{
mt19937 gen;
gen.seed(time(0));
pickANumber(gen, 10, 1);
system("pause");
}

compute signal given (Signal + Noise) and Noise in dBm

Suppose we know (S + N) with x dBm and N with y dBm. Then S = 10 lg(10 ^ (x / 10) - 10 ^ (y / 10)) dBm. The problem is this computation necessitates float point, which is intensive on my embedded system. Is there any way to compute S (in dBm) more efficiently, preferably in integer only? Thanks in advance.
p.s.
S: signal
N: noise
Can you afford two 1D lookup tables? Write
10 lg(10 ^ (x / 10) - 10 ^ (y / 10)) = 10 lg(10 ^ (x / 10)) # lookup by x
+ 10 lg(1 - 10 ^ ((y - x) / 10)) # by y - x

How do I translate this Haskell to F#?

I'm trying to learn F# by translating some Haskell code I wrote a very long time ago, but I'm stuck!
percent :: Int -> Int -> Float
percent a b = (fromInt a / fromInt b) * 100
freqs :: String -> [Float]
freqs ws = [percent (count x ws) (lowers ws) | x <- ['a' .. 'z']]
I've managed this:
let percent a b = (float a / float b) * 100.
although i dont like having to have the . after the 100.
What is the name of the operation I am performing in freqs, and how do I translate it to F#?
Edit: count and lowers are Char -> String -> Int and String -> Int respectively, and I have translated these already.
This is a list comprehension, and in F# it looks like the last two lines below:
// stub out since don't know the implementation
let count (c:char) (s:string) = 4
let lowers (s:string) = 10
// your code
let percent a b = (float a / float b) * 100.
let freq ws = [for x in ['a'..'z'] do
yield percent (count x ws) (lowers ws)]
More generally I think Haskell list comprehensions have the form suggested by the example below, and the corresponding F# is shown.
// Haskell
// [e(x,y) | x <- l1, y <- l2, pred(x,y)]
// F#
[for x in l1 do
for y in l2 do
if pred(x,y) then
yield e(x,y)]
Note that Brian's F# code:
let freq ws = [for x in ['a'..'z'] do yield percent (count x ws) (lowers ws)]
Can be written more elegantly as:
let freq ws = [for x in 'a'..'z' -> percent (count x ws) (lowers ws)]

Resources