How to keep an integral number float in Lua 5.3 - lua

print(2^62)
print(2^63)
print(2^64)
In Lua 5.2, all numbers are doubles. The output of the above code is:
4.6116860184274e+18
9.2233720368548e+18
1.844674407371e+19
Lua 5.3 has support for integers and does automatic conversion between integer and float representation. The same code outputs:
4611686018427387904
-9223372036854775808
0
I want to get the float result. 2.0^64 works, but what if it's not a literal:
local n = io.read("*n") --user input 2
print(n^64)
One possible solution is to divide the number by 1: (n/1)^64 because in / division , the operands are always converted to float, but I'm looking for a more elegant solution.
Tested on Lua 5.3.0 (work2).

io.read("*n") always returns a float. So no surprises there.
If you need to convert an integer to a float, add 0.0 to it.

Related

LUA 5.4 - How to convert 64-bit numbers to hex

I wanted to convert numbers greater than 64 bits, including up to 256 bits number from decimal to hex in lua.
Example:
num = 9223372036854775807
num = string.format("%x", num)
num = tostring(num)
print(num) -- output is 7fffffffffffffff
but if I already add a single number, it returns an error in the example below:
num = 9223372036854775808
num = string.format("%x", num)
num = tostring(num)
print(num) -- error lua54 - bad argument #2 to 'format' (number has no integer representation)
Does anyone have any ideas?
I wanted to convert numbers greater than 64 bits, including up to 256 bits number from decimal to hex in lua.
Well that's not possible without involving a big integer library such as this one. Lua 5.4 has two number types: 64-bit signed integers and 64-bit floats, which are both to limited to store arbitrary 256-bit integers.
The first num in your example, 9223372036854775807, is just the upper limit of int64 bounds (-2^63 to 2^63-1, both inclusive). Adding 1 to this forces Lua to cast it into a float64, which can represent numbers way larger than that at the cost of precision. You're then left with an imprecise float which has no "integer representation" as Lua tells you.
You could trivially reimplement %x yourself, but that wouldn't help you extend the precision/size of floats & ints. You need to find another number representation and find or write a bigint library to go with it. Options are:
String representation: Represent numbers as hex- or bytestrings (base 256).
Table representation: Represent numbers as lists of numbers (base 2^x where x is < 64)

Bad argument to 'random'

This is my code
while true do
script.Parent.Position = Vector3.new((math.random(-41.994,15.471)),0.5,(math.random(129.514,69.442)))
script.Parent.Color = Color3.new(math.random(0,255), math.random(0,255), math.random(0,255))
wait(1)
end
The programming language I am using is Lua
When I try to use this code I am presented with this error:
"15:50:47.926 - Workspace.rock outer walls.Model.Rocks.Part0.Script:2: bad argument #2 to 'random' (interval is empty)"
The purpose of the code is to randomly teleport the part the script is in around but not to far away and at the same y axis.
Can somebody please give me some form of explanation
Ps. A while ago I made a rude post on this website because I was confused at how to do a lot of things and now I understand some stuff better so I would like to apologize for my idiocy ~Zeeen
In Lua, math.random can be called 3 ways:
with no arguments
with 1 integer argument
with 2 integer arguments
It does not accept values like -41.994 or 15.471 this is why you're getting the error.
If your change your values to -41 or 15 you shouldn't see an error any more.
Lua 5.3 reference manual: http://www.lua.org/manual/5.3/manual.html#pdf-math.random
math.random ([m [, n]])
When called without arguments, returns a pseudo-random float with uniform distribution in the range [0,1). When called with two integers m and n, math.random returns a pseudo-random integer with uniform distribution in the range [m, n]. (The value n-m cannot be negative and must fit in a Lua integer.) The call math.random(n) is equivalent to math.random(1,n).
This function is an interface to the underling pseudo-random generator function provided by C.
As Nifim's answer correctly points out, there are three ways to call math.random in Lua.
With no arguments, it returns a real number in the range 0.0 to 1.0.
With one or two integer arguments, it returns an integer.
None of these directly give you want you want, which I presume is a random real number in a specified range.
To do that, you'll need to call math.random with no arguments and then adjust the result.
For example, if you wanted a random number between 5.0 and 10.0, you could use
math.random() * 5.0 + 5.0
Consider writing your own wrapper function that takes two floating-point arguments and calls math.random.
function random_real(x, y)
return x + math.random() * (y-x)
end

Lua string.format ("%d") fails for some integers

I am using lua 5.3.2 and the following piece of code gives me an error:
string.format("%d", 1.16 * 100)
whereas the following line works fine
string.format("%d", 1.25 * 100)
This is probably related to this question but the failure depends on the floating point value. Given that, in my case, a local variable (v) holds the float value, and is generated by an expresson that produces a value between 0 and 2 rounded to 2 decimal places.
How can I modify the code to ensure this doesn't fail for any possible value of v ?
You can use math.floor to convert to integer and add +0.5 if you need to round it: math.floor(1.16 * 100 + 0.5). Alternatively, "%.0f" should have the desired effect as well.

Lua: converting from float to int

Even though Lua does not differentiate between floating point numbers and integers, there are some cases when you want to use integers. What is the best way to covert a number to an integer if you cannot do a C-like cast or without something like Python's int?
For example when calculating an index for an array in
idx = position / width
how can you ensure idx is a valid array index? I have come up with a solution that uses string.find, but maybe there is a method that uses arithmetic that would obviously be much faster. My solution:
function toint(n)
local s = tostring(n)
local i, j = s:find('%.')
if i then
return tonumber(s:sub(1, i-1))
else
return n
end
end
You could use math.floor(x)
From the Lua Reference Manual:
Returns the largest integer smaller than or equal to x.
Lua 5.3 introduced a new operator, called floor division and denoted by //
Example below:
Lua 5.3.1 Copyright (C) 1994-2015 Lua.org, PUC-Rio
>12//5
2
More info can be found in the lua manual
#Hofstad is correct with the math.floor(Number x) suggestion to eliminate the bits right of the decimal, you might want to round instead. There is no math.round, but it is as simple as math.floor(x + 0.5). The reason you want to round is because floats are usually approximate. For example, 1 could be 0.999999996
12.4 + 0.5 = 12.9, floored 12
12.5 + 0.5 = 13, floored 13
12.6 + 0.5 = 13.1, floored 13
local round = function(a, prec)
return math.floor(a + 0.5*prec) -- where prec is 10^n, starting at 0
end
why not just use math.floor()? it would make the indices valid so long as the numerator and denominator are non-negative and in valid ranges.

Small numbers in Objective C 2.0

I created a calculator class that does basic +,-, %, * and sin, cos, tan, sqrt and other math functions.
I have all the variables of type double, everything is working fine for big numbers, so I can calculate numbers like 1.35E122, but the problem is with extremely small numbers. For example if I do calculation 1/98556321 I get 0 where I would like to get something 1.01464E-8.
Should I rewrite my code so that I only manipulate NSDecimalNumber's and if so, what do I do with sin and cos math functions that accept only double and long double values.
1/98556321
This division gives you 0 because integer division is performed here - the result is an integer part of division. The following line should give you floating point result:
1/(double)98556321
integer/integer is always an integer
So either you convert the upper or the lower number to decimal
(double)1/98556321
or
1/(double)98556321
Which explicitely convert the number to double.
Happy coding....

Resources