I've used this in other languages, but lua seems to be lacking this rather useful function.
Could one of you nice chappies provide me a lua function to get the sign of the number passed to it?
function math.sign(x)
if x<0 then
return -1
elseif x>0 then
return 1
else
return 0
end
end
Just in case anyone stumbles on this one:, here's my somehow shorter version:
function sign(x)
return x>0 and 1 or x<0 and -1 or 0
end
I think the idea is to return 1 or -1 to represent positive or negative. I don't think you would want it to return 0. Could have disastrous effects. Imagine trying to change the sign of a value by multiplying it by sign(x) when it returns 0. Instead of changing the sign you'd change the value to 0.
I'd stick with
function sign(x)
return (x<0 and -1) or 1
end
With LuaJIT, if the sign function gets JIT-compiled, this is actually faster:
function sign(x)
return math.max(math.min(x * 1e200 * 1e200, 1), -1)
end
The reason is that it avoids branches, which can be expensive. The double multiplication ensures that the result is correct even with inputs in the denormal range. Infinity can't be used because with an input of zero, it would produce NaN.
Tested in x86 only. I can't guarantee that it's the fastest in other processors supported by LuaJIT.
I built this one because I needed exact handling for -0 and +0 as well as for nan which all the other versions do not handle.
The idea is to interpret the sign bit directly and have a branchless version for this test. In pure Lua you'd have to go with tostring(x) checks +-0.
local _sign_helper = ffi.new("union { double d; uint64_t ul; int64_t l; }[1]")
local function sign(num)
-- to get access to the bit representation of double
_sign_helper[0].d = num
-- reinterpret it as ulong to access the sign bit
-- 1. move the bit down to the first bit
-- 2. multiply by -2 to move the range from 0/1 to 0/-2
-- 4. add 1 to reduce the range to -1/1
-- one test version for NaN handling (might be faster, did not test.)
-- return num ~= num and num or (tonumber(bit.rshift(_sign_helper[0].ul, 63)) * -2 + 1)
-- branchless version: num - num will always be 0 except for nan.
return (tonumber(bit.rshift(_sign_helper[0].ul, 63)) * -2 + 1) * ((num - num + 1) / 1)
end
print("(number < 0)", sign(-3)) -- > -1
print("(number > 0)", sign(3)) -- > 1
print("(nan)", sign(0 / 0)) -- > nan
print("(-inf)", sign(-0 / 1)) -- > -1
print("(+inf)", sign(0 / 1)) -- > 1
print("(+0)", sign(0)) -- > 1
print("(-0)", sign(-0)) -- > -1
You can also get the sign of a number like this:
x/ math.abs(x)
I'd only use that one for integers and since Lua doesn't distinguish ints from floats, I'd not use it in Lua at all.
A variation of that could be
function sign(x)
if x<0 then
return "-"
elseif x>0 then
return "+"
else
return ""
end
end
Mathematically, the sign is '+' or '-' (a symbol), not a number (as +1 or -1)
You can check for the sign like this:
i = -2
if i == math.abs(i) then -- or i >= 0
print "positive"
else
print "negative"
end
Related
The following is the code of my function
function myfunction ( ... )
local tbl = table.pack(...)
for _, v in ipairs(tbl) do
if type(v) ~= 'number' then
print('Error: Something different is expected.')
return
elseif v~= math.abs(v) then
print('Error: Your input needs slight modification.')
return
end
end
if some condition then
**recursive call to myfunction**
else
some result
end
end
The function works fine and it gives expected results to me. But the problem as one can observe that function is calling itself in recursive manner. So the first part of the code which I am giving below also gets repeated several times during each recursive call. Obviously I want to check input only once and exit the function if it is incorrect. If input is correct, then it should not be checked every recursive call. So how the code can be optimized for this purpose. Can some value be assigned to global variable and then use it somewhere inside the function (in if else condition) to avoid repetition. But again the check for value will get repeat (though it is less costly compared to the current approach. The problem is to avoid repetition of the following code (which is part of above code).
for _, v in ipairs(tbl) do
if type(v) ~= 'number' then
print('Error: Something different is expected.')
return
elseif v~= math.abs(v) then
print('Error: Your input needs slightly modified')
return
end
end
As an example, consider the following function.
function factorial(n)
if (n == 0) then
return 1
else
return n * factorial(n - 1)
end
end
When factorial(9.3) is executed it results into stack overflow as no error input check is involved. To handle this the following error mechanism is added.
function factorialwithinputcheck(n)
if type(n) ~= 'number' then
error('only numbers are expected')
return
elseif n~= math.floor(n) or n~=math.abs(n) then
error('only positive integers are expected')
return
end
if (n == 0) then
return 1
else
return n * factorialwithinputcheck(n-1)
end
end
This function gives error and stops execution whenever input is incorrect. The factorialwithinputcheck(9.3) doesn't result into stack overflow. But again the input check is made in every recursive call. How this code for example can be optimised?
Being more specific as in my comment, I'd propose something like this:
function _factorial(n)
if (n == 0) then
return 1
else
return n * _factorial(n-1)
end
end
function factorialwithinputcheck(n)
if type(n) ~= 'number' then
error('only numbers are expected')
return
elseif n~= math.floor(n) or n~=math.abs(n) then
error('only positive integers are expected')
return
end
if (n == 0) then
return 1
else
return n * _factorial(n-1)
end
end
or hiding _factorial:
function factorialwithinputcheck(n)
local function _factorial(n)
if (n == 0) then
return 1
else
return n * _factorial(n-1)
end
end
if type(n) ~= 'number' then
error('only numbers are expected')
return
elseif n~= math.floor(n) or n~=math.abs(n) then
error('only positive integers are expected')
return
end
if (n == 0) then
return 1
else
return n * _factorial(n-1)
end
end
but again, I'm not completely sure if this way the _factorial function has to be "created" multiple times (which should have a performance impact as well). But maybe this can be figured out with some benchmarking.
EDIT: Oh and if you want some input sanitizing: Up to now, you don't check for negative numbers.
Edit2: And since you ask for general optimization of your factorial function. Yes of course one could convert the recursive procedure into an iterative one (avoiding creating new stack frames that many times).
Using some sort of accumulator (acc) passing n*acc down to the next call, you could alternatively make the function tail recursive, (according to this pil chapter (I hope there is no change in that in more frequent lua verions) lua will then handle this for you).
For example:
local function factorial_rec(n)
local function _factorial(n)
if (n == 0) then
return 1
else
return n * _factorial(n-1)
end
end
if type(n) ~= 'number' then
error('only numbers are expected')
return
elseif n~= math.floor(n) or n~=math.abs(n) then
error('only positive integers are expected')
return
end
if (n == 0) then
return 1
else
return n * _factorial(n-1)
end
end
(but to be honest I don't see much of a performance boost with this (0.000293s vs 0.000354s if I loop over factorial form 0 to 40, numbers starting with 21! are already beyond the range for numbers in lua (for my installation), checked only with a very rudimentary benchmark))
I just found a way that I think simpler and faster to remove decimal using double tilde ~~ in some programming languages.
I'm curious what's the meaning of tilde, then I found out from this answer:
The operator ~ is a binary negation operator (as opposed to boolean
negation), and being that, it inverses all the bits of its operand.
The result is a negative number in two's complement arithmetic.
that answer is for PHP language, and I think it's same for MySQL too. I think I could use ~ to revert negation(also remove decimal) and ~~ to just remove decimal number
I tried in PHP and JS:
single tilde:
~-1 // = 1
~1 // = -1
~-1.55 // = 1
~1.55 // = -1
double tilde:
~~-1 // = -1
~~1 // = 1
~~1.55 // = 1
~~-1.55 // = -1
but why I tried in MySQL shows different result:
select ~1; // 18446744073709551614
select ~-1; // 0
select ~-111; // 110
select ~1.55; // 18446744073709551613
select ~-1.55; // 1
select ~~1; // 1
select ~~-1; // 18446744073709551615
select ~~1.55; // 2
select ~~-1.55; // 18446744073709551614
from above queries, I can get conclusion if ~~ is can be used to remove decimal(with round half up) on positive number, but doesn't work for negative number(will return 18446744073...). And I don't know the use of ~ in MySQL. Anyone can explain it for me?
"... faster to remove decimal ..." -- Don't bother optimizing at this level. Stick to the overall structure of SQL.
For converting floating point values to integers, use a function:
mysql> SELECT FLOOR(12.7), CEIL(12.7), ROUND(12.7), ROUND(12.777, 2), FORMAT(1234.7, 0)\G
*************************** 1. row ***************************
FLOOR(12.7): 12
CEIL(12.7): 13
ROUND(12.7): 13
ROUND(12.777, 2): 12.78
FORMAT(1234.7, 0): 1,235
As for what ~ does with floating-point numbers, we need to get into the IEEE-754 standard. But your eyes may glaze over.
I'm currently learning about recursion, it's pretty hard to understand. I found a very common example for it:
function factorial(N)
local Value
if N == 0 then
Value = 1
else
Value = N * factorial(N - 1)
end
return Value
end
print(factorial(3))
N == 0 is the base case. But when i changed it into N == 1, the result is still remains the same. (it will print 6).
Is using the base case important? (will it break or something?)
What's the difference between using N == 0 (base case) and N == 1?
That's just a coincidence, since 1 * 1 = 1, so it ends up working either way.
But consider the edge-case where N = 0, if you check for N == 1, then you'd go into the else branch and calculate 0 * factorial(-1), which would lead to an endless loop.
The same would happen in both cases if you just called factorial(-1) directly, which is why you should either check for > 0 instead (effectively treating every negative value as 0 and returning 1, or add another if condition and raise an error when N is negative.
EDIT: As pointed out in another answer, your implementation is not tail-recursive, meaning it accumulates memory for every recursive functioncall until it finishes or runs out of memory.
You can make the function tail-recursive, which allows Lua to treat it pretty much like a normal loop that could run as long as it takes to calculate its result:
local function factorial(n, acc)
acc = acc or 1
if n <= 0 then
return acc
else
return factorial(n-1, acc*n)
end
return Value
end
print(factorial(3))
Note though, that in the case of factorial, it would take you way longer to run out of stack memory than to overflow Luas number data type at around 21!, so making it tail-recursive is really just a matter of training yourself to write better code.
As the above answer and comments have pointed out, it is essential to have a base-case in a recursive function; otherwise, one ends up with an infinite loop.
Also, in the case of your factorial function, it is probably more efficient to use a helper function to perform the recursion, so as to take advantage of Lua's tail-call optimizations. Since Lua conveniently allows for local functions, you can define a helper within the scope of your factorial function.
Note that this example is not meant to handle the factorials of negative numbers.
-- Requires: n is an integer greater than or equal to 0.
-- Effects : returns the factorial of n.
function fact(n)
-- Local function that will actually perform the recursion.
local function fact_helper(n, i)
-- This is the base case.
if (i == 1) then
return n
end
-- Take advantage of tail calls.
return fact_helper(n * i, i - 1)
end
-- Check for edge cases, such as fact(0) and fact(1).
if ((n == 0) or (n == 1)) then
return 1
end
return fact_helper(n, n - 1)
end
I've been working through CodeWars katas and I came across a pretty cool solution that someone came up with. The problem I have is I don't understand how it works. I understand some of it like what it is generally doing but not detail specifics. Is it returning itself? How is it doing the calculation? Can someone explain this to me because I really what to learn how to do this. And if you know of any other resources I can read or watch that would be helpful. I didn't see anything like this in the Swift documentation.
func findDigit(_ num: Int, _ nth: Int) -> Int {
let positive = abs(num)
guard nth > 0 else { return -1 }
guard positive > 0 else { return 0 }
guard nth > 1 else { return positive % 10 }
return findDigit(positive / 10, nth - 1) }
For context:
Description:
The function findDigit takes two numbers as input, num and nth. It outputs the nth digit of num (counting from right to left).
Note
If num is negative, ignore its sign and treat it as a positive value.
If nth is not positive, return -1.
Keep in mind that 42 = 00042. This means that findDigit(42, 5) would return 0.
Examples
findDigit(5673, 4) returns 5
findDigit(129, 2) returns 2
findDigit(-2825, 3) returns 8
findDigit(-456, 4) returns 0
findDigit(0, 20) returns 0
findDigit(65, 0) returns -1
findDigit(24, -8) returns -1
Greatly appreciate any help. Thanks.
This is a simple recursive function. Recursive means that it calls itself over and over until a condition is satisfied that ends the recursion. If the condition is never satisfied, you'll end up with an infinite recursion which is not a good thing :)
As you already understand the purpose of the function, here are the details of how it works internally:
// Saves the absolute value (removes the negative sign) of num
let positive = abs(num)
// Returns -1 if num is 0 or negative
guard nth > 0 else { return -1 }
// Returns 0 if the absolute value of num is 0 (can't be negative)
guard positive > 0 else { return 0 } // Could be guard positive == 0
// nth is a counter that is decremented with every recursion.
// positive % 10 returns the remainder of positive / 10
// For example 23 % 10 = 3
// In this line it always returns a number from 0 - 9 IF nth <= 0
guard nth > 1 else { return positive % 10 }
// If none of the above conditions are true, calls itself using
// the current absolute value divided by 10, decreasing nth.
// nth serves to target a different digit in the original number
return findDigit(positive / 10, nth - 1)
Let's run through an example step by step:
findDigit(3454, 3)
num = 3454, positive = 3454, nth = 3
-> return findDigit(3454 / 10, 3 - 1)
num = 345, positive = 345, nth = 2 // 345, not 345.4: integer type
-> return findDigit(345 / 10, 2 - 1)
num = 35, positive = 35, nth = 1
-> return 35 % 10
-> return 5
It is a recursive solution. It does not return itself, per se, it calls itself on a simpler case, until it gets to a base case (here a 1 digit number). So for example, let us trace through what it does in your first example:
findDigit(5673, 4) calls
findDigit (567, 3) calls
findDigit (56,2) calls
findDigit (5,1) which is the base case which returns 5 which bubbles all the way back up to the surface.
This is a recursive algorithm. It works by solving the original problem by reducing it to a smaller problem of the same time, then solving that, recursively, until a base case is hit.
I think you'll have a much easier time understanding it if you see the calls being made. Of course, it's best to step through this in the debugger to really see what's going on. I've numbered the sections of interest to refer to them below
func findDigit(_ num: Int, _ nth: Int) -> Int {
print("findDigit(\(num), \(nth))") //#1
let positive = abs(num) // #2
guard nth > 0 else { return -1 } // #3
guard positive > 0 else { return 0 } // #4
guard nth > 1 else { return positive % 10 } // #5
return findDigit(positive / 10, nth - 1) // #6
}
print(findDigit(5673, 4))
I print out the function and its parameters, do you can see what's going on. Here's what's printed:
findDigit(5673, 4)
findDigit(567, 3)
findDigit(56, 2)
findDigit(5, 1)
5
Take the positive value of num, so the - sign doesn't get in the way.
Assert that the nth variable is greater than 0. Since the digit counting in this problem, any value equal to less 0 is invalid. In such a case, -1 is returned. This is very bad practice in Swift. This is what Optionals exist for. It's much better to make this function return Int? and returning nil to represent an error in the nth variable.
Assert that the positive variable is greater than 0. The only other possible case is that positive is 0, in which case its digit (for any position) is 0, so that's why you have return 0.
Assert that nth is greater than 1. If this is not the case, then nth must be 1 (the guard numbered #3 ensures it can't be negative, or 0. In such a case, the digit in the first position of a decimal number is that number modulo 10, hence why positive % 10 is returned.
If we reach this line, than we know we have a sane value of nth (> 0), which isn't 1, and we have a positive number greater than 0. Now we can proceed to solve this problem by recursing. We'll divid positive by 10, and make it into the new nth, and we'll decrement nth, because what is the nth digit of this call, will be in the n-1 th spot of the next call.
Someone by the name of JohanWiltink on CodeWars answered my question. But I chose to accept Nicolas's for the detail.
This was JohanWiltink explanation:
The function does not return itself as a function; it calls itself with different arguments and returns the result of that recursive call (this is possibly nested until, in this case, nth=1).
findDigit(10,2) thus returns the value of findDigit(1,1).
If you're not seeing how this works, try to work out by hand what e.g. findDigit(312,3) would return.
Thanks so much to everyone that answered! Really appreciate it!
This isn't necessarily a programming question but i'm sure you folks know how to do it. How would i convert floating point numbers into binary.
The number i am looking at is 27.625.
27 would be 11011, but what do i do with the .625?
On paper, a good algorithm to convert the fractional part of a decimal number is the "repeated multiplication by 2" algorithm (see details at http://www.exploringbinary.com/base-conversion-in-php-using-bcmath/, under the heading "dec2bin_f()"). For example, 0.8125 converts to binary as follows:
1. 0.8125 * 2 = 1.625
2. 0.625 * 2 = 1.25
3. 0.25 * 2 = 0.5
4. 0.5 * 2 = 1.0
The integer parts are stripped off and saved at each step, forming the binary result: 0.1101.
If you want a tool to do these kinds of conversions automatically, see my decimal/binary converter.
Assuming you are not thinking about inside a PC, just thinking about binary vs decimal as physically represented on a piece of paper:
You know .1 in binary should be .5 in decimal, so the .1's place is worth .5 (1/2)
the .01 is worth .25 (1/4) (half of the previous one)
the .001 is worth (1/8) (Half of 1/4)
Notice how the denominator is progressing just like the whole numbers to the left of the decimal do--standard ^2 pattern? The next should be 1/16...
So you start with your .625, is it higher than .5? Yes, so set the first bit and subtract the .5
.1 binary with a decimal remainder of .125
Now you have the next spot, it's worth .25dec, is that less than your current remainder of .125? No, so you don't have enough decimal "Money" to buy that second spot, it has to be a 0
.10 binary, still .125 remainder.
Now go to the third position, etc. (Hint: I don't think there will be too much etc.)
There are several different ways to encode a non-integral number in binary. By far the most common type are floating point representations, especially the one codified in IEEE 754.
the code works for me is as below , you can use this code to convert any type of dobule values:
private static String doubleToBinaryString( double n ) {
String val = Integer.toBinaryString((int)n)+"."; // Setting up string for result
String newN ="0" + (""+n).substring((""+n).indexOf("."));
n = Double.parseDouble(newN);
while ( n > 0 ) { // While the fraction is greater than zero (not equal or less than zero)
double r = n * 2; // Multiply current fraction (n) by 2
if( r >= 1 ) { // If the ones-place digit >= 1
val += "1"; // Concat a "1" to the end of the result string (val)
n = r - 1; // Remove the 1 from the current fraction (n)
}else{ // If the ones-place digit == 0
val += "0"; // Concat a "0" to the end of the result string (val)
n = r; // Set the current fraction (n) to the new fraction
}
}
return val; // return the string result with all appended binary values
}