❔ ✅ Dice Roll with Generic Math
Has someone use non-generic funcs with generic math... The solution that I have found is a bit hack.
There would be solutions that dont involves a bunch of conditionals?
30 Replies
Unless
Random
implements a generic method that uses INumber
, not really
I guess maybe a switch expression would shorten that code
But that's about itwhy not just
Windows10CE#8553
REPL Result: Success
Result: double
Compile: 560.954ms | Execution: 40.180ms | React with ❌ to remove this embed.
Well it's not exactly the same thing, but it's valid solution, if you don't care about lost in conversion. Well you can also use the double one so there would be no data loss, but less efficient.
Well it's some kind of solution, good to know thx.
oh yeah, I didn't realize you had the the in-betweens as valid states
yeah just swap Next for what you do in RollDouble
probaly is more efficient doing double rather than a bunch of ifs
CreateChecked is the same as
checked((T) input)
If you would rather not lose anything in a conversion and support integers above 64-bit in size, you can:
Stackalloc a byte span
Use the random object to fill it with NexyBytes
Use Unsafe.As
that isnt valid
What do you mean?
If the type is unmanaged, it is
So it would just add support for 128-bit but with a little more tampering you could absolutely do it for arbitrarily large types
it would break floats
Windows10CE#8553
REPL Result: Failure
Exception: ArgumentException
Compile: 475.020ms | Execution: 31.323ms | React with ❌ to remove this embed.
Why did you test that with uint
easiest way to get four bytes of 0xFF
its the same as doing
Windows10CE#8553
REPL Result: Failure
Exception: CompilationErrorException
Compile: 603.036ms | Execution: 0.000ms | React with ❌ to remove this embed.
but easier
also oof
Windows10CE#8553
REPL Result: Success
Console Output
Compile: 607.462ms | Execution: 37.521ms | React with ❌ to remove this embed.
i really shouldnt write unsafe code on discord
but yeah, converting arbitrary bytes to a float is a great way to get random NaNs and Infs
(but yes, if floats weren't involved, and you didn't care about bounding the output, this works fine)
those ifs don't cost you anything, they resolve as constants at jit time and the dead branches get eliminated. the function then will likely get inlined. I'm only not sure about
(object)
conversions, that's a thing I have wondered previously, but the boxing should also get eliminated at jit time
but check out the perf yourself
the above is what I've heard from other peopleall that is correct as well, if you're fine with what you have now
i find
return T.CreateChecked(rng.NextDouble() * sides + 1);
to be much easier to read though
though if you want the range to be [1, sides]
instead of [1, sides + 1)
you have to do
I think you've mentioned that, but double has less precision than e.g. long for integers, so it's not the same
implicit conversion of the compiler from long to double or from int to float is a lie made for convenience
as long as sides isn't very large it doesn't matter much
actually i think this weights to die on sides, actually
hm no that doesnt work either
because for integers it will be very unlikely to get
sides
honestly
i think that works the best?
for both integers and floats that will get you the range [1, sides]
with equal distribution (assuming System.Random has equal distribution, of course)your double can output 0
no it can't
+1 on the end
ah yeah you're right
aaaaaaa
that is check doesnt compile
i'm back with a vengence
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.Have done some benchmarks, there almost no difference it completely depends on the types that is been casted.
And there is a problem with
(T)(object)
which the cast can throw exception while the others don't.I think this can be closed so...
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.