Like the lowest decimal, that isnt 0
This is just not true. By default, just like usual in any other programming languages, when you don’t provide any arguments, it returns a decimal between one and zero. zero included.
Actually, it does. You just do:
local Decimal = math.random(0.0, 120.0)
my bad guys, I thought otherwise
No, This still isn’t true, you would need to use Random.new()
for this:
Random.new():NextNumber(.1, .5) -- 0.15655854882102088 (what I got)
math.random
only returns Integers
Please read my previous post. The expression math.random()
will return decimals. or floats. or doubles. whatever you want to call it.
Mate, pls try out the code I provided
I did, it returns integers not decimals
Putting “.0” really doesn’t make the interpreter interpret the number differently. This isn’t C# or any other statically typed language.
From what I see with math.random()
, it can only handle numbers from the Positives, all the way up to around 1e10
However with the Negatives, it appears to stop at around: -2147483648
from what playing with math.random
returned
Which I’m not sure as the Max Integer limit is at around 9.2 quintillion., while Floats return higher.
If you want larger numbers, try Random.new():NextNumber
Random.new():NextInteger
seems to not cause the Interval is empty
error as it stops at around 9.2 quintillion as if it goes over, it becomes a negative (I could be wrong as I’m not aware of new limits)
That’s because math.random negatives utilizes int32 instead of int64, it seems like that the number becomes negative is just a fail-safe catch to prevent an error with Random.new()
I can’t for the life of me figure out why positive numbers for math.random() go up to 1e10, do you by any chance know why?
Yeah, you basically said why, int32 can only handle numbers at around 2 trillion, I made sure to test and:
print(math.random(2147483646,2147483647)) - Studio
23:09:34.960 2147483646 - Edit
print(math.random(2147483646,2147483647)) - Studio
23:10:49.978 2147483647 - Edit
print(math.random(2147483647,2147483648)) - Studio
23:11:13.853 print(math.random(2147483647,2147483648)):1: invalid argument #2 to 'random' (interval is empty) - Edit
It appears that is the exact limit
1e10
is basically 10 trillion while 1e9
is 1 trillion, so that makes sense
(I think its billion but Im bad at counting, sorry)
But that’s 2.147 billion, not trillion. So it wouldn’t make sense why it goes to 10 billion
Billion = 9 zeros
Trillion = 12 zeros
For some reason i always confuse billion with trillion.
It you want really, really small decimals, just divide the integer range.
This would give you 0.001 to 1 for example
math.random(1,1000) / 1000
Or 0.000001 to 1, etc.
math.random(1,1000000) / 1000000
[edit] Hit wrong reply button
Okay, no.
print(math.random()) --> 0.245837...
Second of all, there isn’t really an answer to this. It’s a very low unknown number.
It’s possible that math.random()
uses 64-bit floats, but I believe the old library functions use 32-bit floats. If that’s indeed the case, the smallest number greater than zero is 1.40129846432e-45
, or a 1 preceded by 44 zeroes.
How are you testing that?
It’s actually faster to multiply by the integer range.
math.random() * 1000
For what it’s worth, the actual limits of signed 32-bit integers are -2,147,483,648
and 2,147,483,647
. Only the right-most digit is different. These numbers are -2^31
and 2^31-1
. For unsigned (positive only) 32-bit integers, the range is from 0
to 2^32
(32 being the number of bits) or about 4 billion. By going from 2^32
to 2^31
with signed numbers, we halve the number which is representative of splitting half of the number above zero and half of it below zero.
Also, 2^31-1
is a Mersenne prime number.
I’m astounded by the misinformed answers here.
Some answers here implicitly misinterpret the topic being about math.random
with one or two arguments (the version that returns the abstract integer data type) rather than math.random
without any arguments, as this is implied by the word “decimal” at the original post and math.random
without argument returns an abstract float whereas math.random
with 1 or 2 arguments returns an abstract integer.
Looking at the source code, math.random
with no argument always uses (not it is possible that but that it does use) C’s double
in Luau; it does not use the C’s float
.
luau/VM at master · Roblox/luau · GitHub
case 0:
{ // no arguments
// Using ldexp instead of division for speed & clarity.
// See http://mumble.net/~campbell/tmp/random_real.c for details on generating doubles from integer ranges.
uint32_t rl = pcg32_random(&g->rngstate);
uint32_t rh = pcg32_random(&g->rngstate);
double rd = ldexp(double(rl | (uint64_t(rh) << 32)), -64);
lua_pushnumber(L, rd); // number between 0 and 1
break;
}
Is there really no answer?
For OP - I believe this section will also be relevant for you, as this section (hopefully) answers the original post.
Look at the Luau source code - luau/lmathlib.cpp at master · Roblox/luau · GitHub
case 0:
{ // no arguments
// Using ldexp instead of division for speed & clarity.
// See http://mumble.net/~campbell/tmp/random_real.c for details on generating doubles from integer ranges.
uint32_t rl = pcg32_random(&g->rngstate);
uint32_t rh = pcg32_random(&g->rngstate);
double rd = ldexp(double(rl | (uint64_t(rh) << 32)), -64);
lua_pushnumber(L, rd); // number between 0 and 1
break;
}
Observing this, you can see that rd
is the value returned for math.random
with no arguments and the value of rd
is defined as ldexp(double(rl | (uint64_t(rh) << 32)), -64)
- ldexp(x, exp)
is abstractly defined as x * 2**exp
. You can also see that rl
and rh
are randomly generated in the range of unsigned 32-bit integers; it could any value from 0
to 2**32-1
but given that it’s randomly generated, we don’t know what the exact value is.
To find the smallest value, find the smallest value of the x
as the exp
is constant, as the abstract definition of ldexp
implies that as the x
approaches to 0
, the return value of ldexp
decreases - but because the x
argument in this case is double(rl | (uint64_t(rh) << 32)
, the smallest value would be rl = 0
, rh = 0
which is ldexp(0.0, -64)
which is 0 * 2**-64
which is 0.0
, but the original post states that the smallest value that isn’t zero, so try rl = 1
, rh = 0
which is ldexp(1.0, -64)
which is 1 * 2**-64
which is 2**-64
.
This concludes that the smallest value math.random
without arguments can theoretically return is 2**-64
in Luau albeit the internal rl
and rh
have to be 0
and 1
respectively which is a 1 in 264 chance of that happening.
math.random
with two arguemnts can handle zero and negative numbers as long as the interval isn’t empty (the upper bound is greater or bigger than the lower bound) - not sure where did you get the statement that it can only handle positive numbers from.
If you provide a Luau native "number"
that is out of the range (of the argument of these functions that internally cast the value to an internal fixed-width integer data type) into both 2-argument version of math.random(x, y)
or Random.new(...):NextNumber(x, y)
it is not always going to “become a negative value” (so that the interval will be empty) as it is an undefined behaviour as internally math.random
uses luaL_checkinteger
to convert from Luau "number"
(which is a double
) to a fixed-width integer, and Random.new(...):NextNumber
perhaps uses something similar.
yo so like whats the lowest number cuz i aint readin allat
ty for ur help tho