3

Assume integer below is produced by a true random number generator, and the number changes randomly between 0 and 255.

let integer = 241 // true random number

For the application I'm working on, I need to convert that number into a floating decimal between 0 and 1 to look more like the result from Math.random().

So,

let float = integer/((2**8)-1)

If integer changes to a new random integer between 0 and 255, will this provide other "quality" floating point numbers? For instance, would requesting Uint16 for numbers between 0–65535 then let float = integer/((2**16)-1) be a better approach just for the greater variety?

Note, my purposes for this is not for security, encryption, or cryptography. I just need the added decimal places similar to Math.random(). I am using these numbers to plug into a normalization transform using Box Müller to create a simulated random walk.

Dshiz
  • 3,099
  • 3
  • 26
  • 53
  • 4
    `integer/(2**8)-1` should we assume that your "true" number generator generates values between 0 and 2**8-1 ? In this case you are missing a pair of parenthesis in your calculation`integer/((2**8)-1)`. – Pac0 Oct 22 '20 at 21:43
  • That may have actually resolved my question... Now that I've added the missing parenthetical, I no longer need Math.random() at all! Thank you! – Dshiz Oct 22 '20 at 21:46
  • 2
    Just so you notice: you are _linearly_ "mapping" the 256 differrent values to approximately equally spaced 256 different values between 0 and 1. There are _many many many_ possible floating point number that will never be generated in that case. Example : 151/255 has some probability to be generated, as do 152/255, but all the number in between have probability zero. I don't know what is your actual goal, so it may or may not be an issue. – Pac0 Oct 22 '20 at 21:47
  • Do you have a suggestion for how to get the floating point numbers in between? I'm getting the numbers from ANU Quantum Number Generator. Their API provides uint8, which is what I'm using, and uint16 -- would uint16 be better? As noted, it's not for cryptography. – Dshiz Oct 22 '20 at 21:51
  • It should be noted that `Math.random()` is not [_truly_ random](https://adtmag.com/Blogs/Dev-Watch/2016/01/random-javascript-fix.aspx) to begin with. – Slbox Oct 22 '20 at 22:00
  • @Slbox, understood... This question should probably be updated given Pac0's comment regarding the parenthesis. The real question might need to be, how to get all floating point values for a random number between 0 and 255. – Dshiz Oct 22 '20 at 22:02
  • 1
    @Dshiz You should definitely update if that's your true question, because that's not at all what I get from the original. – zcoop98 Oct 22 '20 at 22:12
  • Updated @zcoop98. I hope it's clear enough. – Dshiz Oct 22 '20 at 22:20
  • Yes it's clearer. But that's tricky... I think it's a bit more complicated than it may look... – Pac0 Oct 22 '20 at 22:29
  • however, you tell what your goal _isn't_ (crypto or security...) but can you be more specific on what your goal is? – Pac0 Oct 22 '20 at 22:31
  • @Pac0 Question updated – Dshiz Oct 22 '20 at 22:34
  • 2
    To get "more precision", i.e. a wider range of values, you can compose several random values. As you suggested, if you can use 16bits integer, that may help as well. anway, if there are trully random, taking 2 uint8 or 1 uint16 is the same: you get 16 random bits instead of 8. `uint16Random / (2**16 - 1)` could be better and fit your case. If you want 32 bits, you can compose 2 uint16 like this : `((2**16) * uint16Random1) + uint16Random2` and then divide that by `(2 ** 32) - 1`. – Pac0 Oct 22 '20 at 22:35
  • @Pac0 - Okay, now I'm starting to get it! I think I'll just request two uint16's at a time from the ANU Quantum Random Number API and do the math you suggested using the power of 32. This is actually closer to the original code I was basing my work on, but desired "true" random numbers: https://stackoverflow.com/questions/22058195/generating-a-smooth-random-trend-random-walk-in-javascript – Dshiz Oct 22 '20 at 22:37
  • Aside: This may be interesting : https://mumble.net/~campbell/2014/04/28/uniform-random-float – Pac0 Oct 22 '20 at 22:38
  • After reading your edit, I understand that what you need is to have "acceptable precision" so it looks like random walk. I'm not sure my way will be uniform enough, but I believe it's a first start. Check the other link I gave above to make sure you get uniform distribution. – Pac0 Oct 22 '20 at 22:39

1 Answers1

3

In JavaScript, a Number is implemented as a binary floating-point number format with 53 significant bits of precision (more specifically, the binary64 format of IEEE 754).

However, generating a "uniform" floating-point number by multiplying or dividing an integer with a constant (as is commonly the case) will generally leave some floating-point numbers with no chance of occurring, even though they lie in the correct range and even though they can be represented in the floating-point format in question. For more information, see F. Goualard, "Generating Random Floating-Point Numbers by Dividing Integers: a Case Study".

Instead, a more complicated procedure can be done to give each floating-point number the expected probability of occurring (within the limits of the floating-point format), as I have done, for example. Note how non-trivial this procedure is. See also my answer to the question: Random floating point double in Inclusive Range

Peter O.
  • 32,158
  • 14
  • 82
  • 96
  • Do you have a javascript example of what you've done that I can reference? I would greatly appreciate it, and so would anyone else who would like to use the [NPM module I've created](https://www.npmjs.com/package/random-walk). – Dshiz Oct 30 '20 at 00:44
  • I am not aware of any JavaScript implementation of the algorithm I mention. You could try writing one yourself, following the pseudocode I give. – Peter O. Oct 30 '20 at 00:56