We had given task as
Read an angle in degrees, and print the tan, cosec, sec, and cot values of that angle in the same order. To use via the rad() function, convert the angle from degrees to radians for the standard library functions.
For which we written code as
x = io.read()
radianVal = math.rad (x)
io.write(string.format("%.1f ", math.tan(radianVal)),"\n")
io.write(string.format("%.1f ", math.cosh(radianVal)),"\n")
io.write(string.format("%.1f ", math.sinh(radianVal)),"\n")
io.write(string.format("%.1f ", math.cos(radianVal)),"\n")
But output is not as expect, not sure where we went wrong
Run as Custom Input
30
Your Output (stdout)
0.6
1.1
0.5
0.9
Expected Output
0.57735026918963
2.0
1.1547005383793
1.7320508075689
Correct code which is working perfectly is
x = io.read()
function cot(radAngle)
return 1 / math.tan(radAngle)
end
function cosec(radAngle)
return 1 / math.sin(radAngle)
end
function sec(radAngle)
return 1 / math.cos(radAngle)
end
local radAngle = math.rad(x)
print(math.tan(radAngle))
print(cosec(math.rad(x)))
print(sec(math.rad(x)))
print(cot(math.rad(x)))
How can you expect to get the correct result if you calculate cosh(x) instead of csc(x)? You're using the hyperbolic cosine to calcuate the cosecant. I think it is obvious why your results are not accepted.
You use sinh(x) to calculate sec(x) and cos(x) to calculate cot(x).
You're confusing mathematical functions. That's not a Lua programming problem.
I suggest you spend a few hours on researching trigonometric functions.
https://en.wikipedia.org/wiki/Trigonometric_functions
Such values are calcuated using the correct formula or function. Not by using any function of the math library that has a similar name.
cosh is deprecated since Lua 5.3 btw.
You can use math.tan to calculate the tangens of your angle.
For secant, cosecant and cotangens you'll have to implement your own functions.
Also note that the number of decimals might cause issue in result validation. Make sure it is ok to round to 1 decimal.
Example:
There is no function to calculate the cotangent of an angle. So we define one.
function cot(radAngle)
return 1 / math.tan(radAngle)
end
local radAngle = math.rad(30)
print("tan(30°):", math.tan(radAngle))
print("cot(30°):", cot(math.rad(30)))
->
tan(30°): 0.57735026918963
cot(30°): 1.7320508075689
So I have a script that is on repeat, constantly checking a value. However, even if the value is true, the function won't even run at all.
I tried adding "wait()" to solve the problem but that didn't work at all.
useless = 0
wait(1)
repeat
print("watno")
wait()
if script.Parent.Parent.Parent.windowsopen.Value == true then
wait()
for i = 5.5,0,0.1 do
print("wat")
wait()
useless = useless + i
script.Parent.Size = Vector3.new(script.Parent.Size.X, script.Parent.Y - 0.1, script.Parent.Size.Z )
end
elseif script.Parent.Parent.Parent.windowsopen.Value == false then
wait()
end
until false
The "windowsopen" value is always true, but it never runs it.
problem you have most likely caused by your for loop, you should change it to
for i = 55, 0, -1 do
print("wait")
wait()
useless = useless + 0.1*i
script.Parent.Size = Vector3.new(script.Parent.Size.X, script.Parent.Y - 0.1, script.Parent.Size.Z )
end
because (a) if you want to decrease i in loop third parameter should be negative , (b) you really should not use float or double in for loop because of precision\representation: 0.1 may end up represented as 0.1000000000000001 (or something like that) and in i will end up never be equal to zero in loop. For more info check what format lua uses for representing double (i think it is IEEE 754 but i may be wrong) also you can look at https://floating-point-gui.de/
I am working on programming a Markov chain in Lua, and one element of this requires me to uniformly generate random numbers. Here is a simplified example to illustrate my question:
example = function(x)
local r = math.random(1,10)
print(r)
return x[r]
end
exampleArray = {"a","b","c","d","e","f","g","h","i","j"}
print(example(exampleArray))
My issue is that when I re-run this program multiple times (mash F5) the exact same random number is generated resulting in the example function selecting the exact same array element. However, if I include many calls to the example function within the single program by repeating the print line at the end many times I get suitable random results.
This is not my intention as a proper Markov pseudo-random text generator should be able to run the same program with the same inputs multiple times and output different pseudo-random text every time. I have tried resetting the seed using math.randomseed(os.time()) and this makes it so the random number distribution is no longer uniform. My goal is to be able to re-run the above program and receive a randomly selected number every time.
You need to run math.randomseed() once before using math.random(), like this:
math.randomseed(os.time())
From your comment that you saw the first number is still the same. This is caused by the implementation of random generator in some platforms.
The solution is to pop some random numbers before using them for real:
math.randomseed(os.time())
math.random(); math.random(); math.random()
Note that the standard C library random() is usually not so uniformly random, a better solution is to use a better random generator if your platform provides one.
Reference: Lua Math Library
Standard C random numbers generator used in Lua isn't guananteed to be good for simulation. The words "Markov chain" suggest that you may need a better one. Here's a generator widely used for Monte-Carlo calculations:
local A1, A2 = 727595, 798405 -- 5^17=D20*A1+A2
local D20, D40 = 1048576, 1099511627776 -- 2^20, 2^40
local X1, X2 = 0, 1
function rand()
local U = X2*A2
local V = (X1*A2 + X2*A1) % D20
V = (V*D20 + U) % D40
X1 = math.floor(V/D20)
X2 = V - X1*D20
return V/D40
end
It generates a number between 0 and 1, so r = math.floor(rand()*10) + 1 would go into your example.
(That's multiplicative random number generator with period 2^38, multiplier 5^17 and modulo 2^40, original Pascal code by http://osmf.sscc.ru/~smp/)
math.randomseed(os.clock()*100000000000)
for i=1,3 do
math.random(10000, 65000)
end
Always results in new random numbers. Changing the seed value will ensure randomness. Don't follow os.time() because it is the epoch time and changes after one second but os.clock() won't have the same value at any close instance.
There's the Luaossl library solution: (https://github.com/wahern/luaossl)
local rand = require "openssl.rand"
local randominteger
if rand.ready() then -- rand has been properly seeded
-- Returns a cryptographically strong uniform random integer in the interval [0, n−1].
randominteger = rand.uniform(99) + 1 -- randomizes an integer from range 1 to 100
end
http://25thandclement.com/~william/projects/luaossl.pdf
Which is the best efficient way to round up a number and then truncate it (remove decimal places after rounding up)?
for example if decimal is above 0.5 (that is, 0.6, 0.7, and so on), I want to round up and then truncate (case 1). Otherwise, I would like to truncate (case 2)
for example:
232.98266601563 => after rounding and truncate = 233 (case 1)
232.49445450000 => after rounding and truncate = 232 (case 2)
232.50000000000 => after rounding and truncate = 232 (case 2)
There is no build-in math.round() function in Lua, but you can do the following:
print(math.floor(a+0.5)).
A trick that is useful for rounding at decimal digits other than whole integers is to pass the value through formatted ASCII text, and use the %f format string to specify the rounding desired. For example
mils = tonumber(string.format("%.3f", exact))
will round the arbitrary value in exact to a multiple of 0.001.
A similar result can be had with scaling before and after using one of math.floor() or math.ceil(), but getting the details right according to your expectations surrounding the treatment of edge cases can be tricky. Not that this isn't an issue with string.format(), but a lot of work has gone into making it produce "expected" results.
Rounding to a multiple of something other than a power of ten will still require scaling, and still has all the tricky edge cases. One approach that is simple to express and has stable behavior is to write
function round(exact, quantum)
local quant,frac = math.modf(exact/quantum)
return quantum * (quant + (frac > 0.5 and 1 or 0))
end
and tweak the exact condition on frac (and possibly the sign of exact) to get the edge cases you wanted.
To also support negative numbers, use this:
function round(x)
return x>=0 and math.floor(x+0.5) or math.ceil(x-0.5)
end
If your Lua uses double precision IEC-559 (aka IEEE-754) floats, as most do, and your numbers are relatively small (the method is guaranteed to work for inputs between -251 and 251), the following efficient code will perform rounding using your FPU's current rounding mode, which is usually round to nearest, ties to even:
local function round(num)
return num + (2^52 + 2^51) - (2^52 + 2^51)
end
(Note that the numbers in parentheses are calculated at compilation time; they don't affect runtime).
For example, when the FPU is set to round to nearest or even, this unit test prints "All tests passed":
local function testnum(num, expected)
if round(num) ~= expected then
error(("Failure rounding %.17g, expected %.17g, actual %.17g")
:format(num+0, expected+0, round(num)+0))
end
end
local function test(num, expected)
testnum(num, expected)
testnum(-num, -expected)
end
test(0, 0)
test(0.2, 0)
test(0.4, 0)
-- Most rounding algorithms you find on the net, including Ola M's answer,
-- fail this one:
test(0.49999999999999994, 0)
-- Ties are rounded to the nearest even number, rather than always up:
test(0.5, 0)
test(0.5000000000000001, 1)
test(1.4999999999999998, 1)
test(1.5, 2)
test(2.5, 2)
test(3.5, 4)
test(2^51-0.5, 2^51)
test(2^51-0.75, 2^51-1)
test(2^51-1.25, 2^51-1)
test(2^51-1.5, 2^51-2)
print("All tests passed")
Here's another (less efficient, of course) algorithm that performs the same FPU rounding but works for all numbers:
local function round(num)
local ofs = 2^52
if math.abs(num) > ofs then
return num
end
return num < 0 and num - ofs + ofs or num + ofs - ofs
end
Here's one to round to an arbitrary number of digits (0 if not defined):
function round(x, n)
n = math.pow(10, n or 0)
x = x * n
if x >= 0 then x = math.floor(x + 0.5) else x = math.ceil(x - 0.5) end
return x / n
end
For bad rounding (cutting the end off):
function round(number)
return number - (number % 1)
end
Well, if you want, you can expand this for good rounding.
function round(number)
if (number - (number % 0.1)) - (number - (number % 1)) < 0.5 then
number = number - (number % 1)
else
number = (number - (number % 1)) + 1
end
return number
end
print(round(3.1))
print(round(math.pi))
print(round(42))
print(round(4.5))
print(round(4.6))
Expected results:
3, 3, 42, 5, 5
I like the response above by RBerteig: mils = tonumber(string.format("%.3f", exact)).
Expanded it to a function call and added a precision value.
function round(number, precision)
local fmtStr = string.format('%%0.%sf',precision)
number = string.format(fmtStr,number)
return number
end
Should be math.ceil(a-0.5) to correctly handle half-integer numbers
Here is a flexible function to round to different number of places. I tested it with negative numbers, big numbers, small numbers, and all manner of edge cases, and it is useful and reliable:
function Round(num, dp)
--[[
round a number to so-many decimal of places, which can be negative,
e.g. -1 places rounds to 10's,
examples
173.2562 rounded to 0 dps is 173.0
173.2562 rounded to 2 dps is 173.26
173.2562 rounded to -1 dps is 170.0
]]--
local mult = 10^(dp or 0)
return math.floor(num * mult + 0.5)/mult
end
For rounding to a given amount of decimals (which can also be negative), I'd suggest the following solution that is combined from the findings already presented as answers, especially the inspiring one given by Pedro Gimeno. I tested a few corner cases I'm interested in but cannot claim that this makes this function 100% reliable:
function round(number, decimals)
local scale = 10^decimals
local c = 2^52 + 2^51
return ((number * scale + c ) - c) / scale
end
These cases illustrate the round-halfway-to-even property (which should be the default on most machines):
assert(round(0.5, 0) == 0)
assert(round(-0.5, 0) == 0)
assert(round(1.5, 0) == 2)
assert(round(-1.5, 0) == -2)
assert(round(0.05, 1) == 0)
assert(round(-0.05, 1) == 0)
assert(round(0.15, 1) == 0.2)
assert(round(-0.15, 1) == -0.2)
I'm aware that my answer doesn't handle the third case of the actual question, but in favor of being IEEE-754 compliant, my approach makes sense. So I'd expect that the results depend on the current rounding mode set in the FPU with FE_TONEAREST being the default. And that's why it seems high likely that after setting FE_TOWARDZERO (however you can do that in Lua) this solution would return exactly the results that were asked for in the question.
Try using math.ceil(number + 0.5) This is according to this Wikipedia page. If I'm correct, this is only rounding positive integers. you need to do math.floor(number - 0.5) for negatives.
If it's useful to anyone, i've hash-ed out a generic version of LUA's logic, but this time for truncate() :
**emphasized text pre-apologize for not knowing lua-syntax, so this is in AWK/lua mixture, but hopefully it should be intuitive enough
-- due to lua-magic alrdy in 2^(52-to-53) zone,
-- has to use a more coarse-grained delta than
-- true IEEE754 double machineepsilon of 2^-52
function trunc_lua(x,s) {
return \
((x*(s=(-1)^(x<-x)) \
- 2^-1 + 2^-50 \ -- can also be written as
\ -- 2^-50-5^0/2
- _LUAMAGIC \ -- if u like symmetric
\ -- code for fun
+ _LUAMAGIC \
) *(s) };
It's essentially the same concept as rounding, but force-processing all inputs in positive-value zone, with a -1*(0.5-delta) offset. The smallest delta i could attain is 2^-52 ~ 2.222e-16.
The lua-magic values must come after all those pre-processing steps, else precision-loss may occur. And finally, restore original sign of input.
The 2 "multiplies" are simply low-overhead sign-flipping. sign-flips 4 times for originally negative values (2 manual flips and round-trip to end of mantissa), while any x >= 0, including that of -0.0, only flips twice. All tertiary function calling, float division, and integer modulus is avoided, with only 1 conditional check for x<0.
usage notes :
(1) doesn't perform checks on input for invalid or malicious payload,
(2) doesn't use quickly check for zero,
(3) doesn't check for extreme inputs that may render this logic moot, and
(4) doesn't attempt to pretty format the value
if not exist math.round
function math.round(x, n)
return tonumber(string.format("%." .. n .. "f", x))
end
I tried to figure out the difference between math.fmod and math.mod with the following code:
a={9.5 ,-9.5,-9.5,9.5}
b={-3.5, 3.5,-3.5,3.5}
for i=1,#a do
if math.fmod(a[i],b[i])~=math.mod(a[i],b[i]) then
print("yeah")
end
end
It never prints "yeah"!
What should I put in array a and b to see "yeah"?
The documentation of math.fmod() say that it returns the remainder of the division of x by y that rounds the quotient towards zero.
math.mod is the same function as math.fmod. Actually, math.mod exists only for compatibility with previous versions; it's not listed in the manual. Try math.modf instead of math.mod in your code.
Modulo in Lua is defined as "the remainder of a division that rounds the quotient towards minus infinity" -Link here - Which is different from the definition of fmod (as you quoted in your original post).
What you really need to do is use the modulo operator (%) rather than math.mod:
a={9.5 ,-9.5,-9.5,9.5}
b={-3.5, 3.5,-3.5,3.5}
for i=1,#a do
if math.fmod(a[i],b[i]) ~= a[i] % b[i] then
print("yeah")
end
end