No announcement yet.

SuperRandom Post

  • Filter
  • Time
  • Show
Clear All
new posts

  • SuperRandom Post

    Random numbers from Math classes can tend to not be all that random. I had a little bitty idea. What if every bit of a (u)int was randomly generated? This gave me a random number that spans the entire range of an (u)int, and that's great but, that's not how Math.random() actually works so, I simply divide my product by the maximum possible number and I get very very close to the range of decimals Math.random() would generate. I threw some doubling up and multiplication of squares in there mostly to force the random generator to run more times and hopefully make the product even more random.

    here are some results for anyone interested. I'm not saying anything about these results ... good, bad, ugly I have no idea. They are just a small example of "the results". I mean, the backbone of this system is the very Math.random() function that isn't all that damn random so... lol. I called random(), Int() and UInt() 100 times and the little label to the left of each result reflects which one was called for that line.

    EDIT (new results):
    I considered that my last results couldn't be compared to anything. Too many different infos and too little space. This time I ran just random, cut it off at the thousandths place and multiplied by 1000. This gives us a slew of random 0 to 999. Judging by these results I don't feel like its random enough. There isn't enough "less than one hundred" (there isn't any in this picture) and at least one number repeats ... right after its first self O.o . Truly random numbers are no joke. I don't know what I'm doing or where to go from here. This was just my little idea implemented.

    Last edited by MadGypsy; 07-01-2018, 09:15 PM.

  • #2
    I didn't know what else to do with this but I noticed there was only one function that had more than one line of code in it. My mini-challenge was to make it one line and get the exact same results and primary functionality. It wasn't that hard. It's the exact same thing as the old thing backwards and procedural. I also reworked random() a hair to define some static boundaries for the decimal to fall within.

    Last edited by MadGypsy; 07-01-2018, 11:18 PM.


    • #3
      I'd like to share something that I noticed and believe may be the reason that random is not that random. I ran the test in the below image numerous times and always got pretty similar results, with the split being very close to 50%. I opine that if the number was truly random you would never get such even-steven results. It would always be notably, and maybe even grossly, disproportionate. 50% is far too "we all get the same amount of turns" to be considered random.

      So what's the solution? Create a disproportionator? A disproportionator would be it's own random and completely resigning random is way beyond the scope of my little test but, it was a chill little experiment on a lazy Sunday.

      Last edited by MadGypsy; 07-02-2018, 12:25 AM.


      • #4
        Firstly, there's nothing random about random().
        Secondly, users would complain if it actually was random!
        Thirdly, the higher bits of a random number are generally considered more random than the low bits, partly because if you're plotting the results on a graph then you'll generally need to ignore some of the lower bits for your graph to be readable. Quake likes to use modulo or bitmasking on the lower bits. Hence why eg the rand() function provided by emscripten can then make all the particles from an effect move in the exact same direction.

        If you actually want a true random number then you're going to have to be prepared to write your own random number generator (like I said - there's nothing random about random).
        eg here's one I simplified from glibc...
        static int randstate = 0xdeadbeef;
        #define glibcrand() (randstate = ((randstate * 1103515245) + 12345) & 0x7fffffff)
        #define glibcsrand(n) (randstate = n)
        As you can see, it doesn't have to be that complex, but anything dealing with bitpatterns is going to have a patterned result. The alternative is to loop through a table, which in many ways is worse...

        Years ago, I pointed out to bigfoot that some version of ktx failed to keep random time-dependant.
        Which means that he was able to use the two visible bits of randomness from swinging his axe to figure out where in the random number generator's pattern it was, and then reliably select his spawn spot with a few more swings. It didn't take very many swings to get it synced, either.
        Of course, another player doing the same thing would have screwed it up, but that's not quite the point...

        See also:
        Some Game Thing


        • #5
          Real good info, brother. Thank you. I can't say that I actually need any numbers (random or not). I was outside working on some things yesterday and for whatever reason the non-randomness of random popped in my head and I had my little idea of generating every bit randomly. I guess what I'm trying to say is that I'm not making this for anything other than "educational purposes" ... a little experiment where I get to play with some code.

          I like the code you posted though and I'm sure I'll mess around with a variation of it tonight. I don't really program anymore but, I got a little bug recently to play around with really simple ideas in code. I wrote a Keyboard event class that can handle the entire keyboard on one persistant listener. I got the idea when I saw some code creating listeners for every desired key and it struck me that everyone does that even though having all those listeners running is not at all necessary and actually kind of expensive. Now it's real simple.

          Keys.areKeys([KEYCODE, KEYCODE])

          and if you have to listen for the actual event
          Keys.listen(KEYCODE, CALLBACK, TYPE);
          // TYPE = UP, DOWN or UP_N_DOWN

          Basically I created a key pool.

          I was beginning to think I was the only xkcd fan. I never see his comics anywhere but his site and mine and I never see him mentioned anywhere.


          • #6
            I created one other little script that I'm a little proud of. The context is 2d orthographic top down perspective where the player needs to rotate in the direction of keypresses. My code finds the shortes distance of rotation by first converting the radians to angles (-180 to 180) and then converting that to 0 to 359. From there it's simply a matter of comparing differences. I'm a little proud of this script because it was entirely invented in my head. I'm sure I just figured out something that game programmers already do or maybe my way is a perfectly working noobish way. I can't say either way. All I can say is faced with the problem and not using any paper or internets it was pretty complicated to flesh this out in my head. Well, that is until I stopped trying to fuck with radians in my head and decided to convert everything to uint degrees.

                     *     I'm sure this entire function could use just radians to make all of it's decisions. I don't want that.
                     *     I want clear operations in whole numbers that immediately mean something to me
                     * @param    cont - the entity orientation information from the controller
                    public function update(cont:Object):void
                        x = cont.x; y = cont.y;                        //set new x|y
                        r = rotation * (180 / Math.PI);                //current rotation as degrees
                        if (r != cont.r)                            //if we aren't already at the proper rotation (in degrees)
                            //convert rotations to a 360 degree system and find the distance of rotation (in degrees) for both directions
                            a = (r        + 360) % 360;                //convert this.rotation to 0 - 359
                            b = (cont.r    + 360) % 360;                //convert new  rotation to 0 - 359
                            c = Math.max(a, b) - Math.min(a, b);    //get the inner turn distance
                            d = 360 - c;                            //get the outer turn distance
                            //turn in the direction with the shortest distance to desired rotation
                            if (a < b)    {                            //if target current rotation is less than desired rotation         (in degrees)
                                if(c < d) rotation += rspdrad;        //if the inner distance is less than the outer distance             (increment in radians)
                                else       rotation -= rspdrad;        //else the outer distance is less than the inner distance         (decrement in radians)
                            } else {                                //else if the desired rotation is less than the current rotation (in degrees)
                                if(c < d) rotation -= rspdrad;        //if the inner distance is less than the outer distance             (decrement in radians)
                                else       rotation += rspdrad;        //else the outer distance is less than the inner distance         (increment in radians)
                            //if we're within "rspeed" distance of rotation (from either direction) snap to the desired rotation    (in degrees)
                            if ((c < rspeed) || (d < rspeed)) rotation = cont.r * (Math.PI / 180);    //...and assign it as radians
            sorry so sloppy looking. This site destroys my editor format ... generally why I post images.
            Last edited by MadGypsy; 07-02-2018, 02:04 PM.