calculate multiple input value in javascript - javascript

I have 5 input fields (range sliders) and I'm trying to return a result when any of the input values changes.
The problem is "value4" is used 2 times in the equation and this is causing the problem. If I change "value4" my result does not change.
function output(){
var value1 = document.getElementById('NumberOfEmployees_input').value;
var value2 = document.getElementById('AverageSalary_input').value;
var value3 = document.getElementById('AverageTime_input').value;
var value4 = document.getElementById('WorkdaysWeek_input').value;
var value5 = document.getElementById('AccountingHours_input').value;
document.getElementById('saving').innerHTML =
(((parseInt(value1) * parseInt(value2))/(parseInt(value4) * parseInt(1920))) * (parseInt(value3) * parseInt(value4) * parseInt(48)))
+ (parseInt(value5) * parseInt(13500)) - parseInt(183600);
}
Can anybody give me a hint?
Thank you!

Your equation can be simplified, you added too many brackets (I removed the parseInt() function to make it more readable).
It is equivalent to:
value4 is canceled:
You may have made an error in your equation.

The code is very difficult to read. I suggest simplifying the code by first, shortening the variable names. Then apply parseInt at an early stage to reduce clutter afterwards.
Plus, there is no need to parseInt(123) since 123 is already Integer.
function output(){
var v1 = parseInt(document.getElementById('NumberOfEmployees_input').value);
var v2 = parseInt(document.getElementById('AverageSalary_input').value);
var v3 = parseInt(document.getElementById('AverageTime_input').value);
var v4 = parseInt(document.getElementById('WorkdaysWeek_input').value);
var v5 = parseInt(document.getElementById('AccountingHours_input').value);
var n = v1 * v2; // nominator
var d = v4 * 1920 * v3 * v4 * 48; // denominator
document.getElementById('saving').innerHTML = (n/d) + (v5 * 13500) - 183600;
}

Here is your equation
(
(
(parseInt(value1) * parseInt(value2))
/
(parseInt(value4) * parseInt(1920))
) *
(parseInt(value3) * parseInt(value4) * parseInt(48))
)
+ (parseInt(value5) * parseInt(13500))
- parseInt(183600);
v1 • v2
(----------- • v3 • v4 • 48) + (v5 • 13500) - 183600
v4 • 1920
// valueN has been substituted with vN
By observation, v4 cancels out.
This reduces your chain of math to
( (parseInt(value1)*parseInt(value2)*parseInt(value3)*48) / 1920 )
+ (parseInt(value5) * 13500)
- 183600;
Note that originally, v4 = 0 would fail. This may or may not be intended.
To make your code more readable you can separate the numerator and denominator as so
n = parseInt(value1) * parseInt(value2) * parseInt(value3) * 48
document.getElementById('saving').innerHTML = (n/1920) + (v5 * 13500) - 183600;
While this might not answer your question of using 2 input values, this provides a workaround in your situation. You didn't seem to realise this when you posted your question. Perhaps you misplaced a bracket or made an error in your calculations?

Related

Converting excel formulae to JS?

I have this formula and it uses powers e.g. '10 to the power 30'
=B2*(B3/12) / (1-(1+(B3/12)) ^ -B6)
The problem is that I can't put ^ in JS/jQuery, I have to use Math.pow() as the equivalent.
I've tried quite a few different positions but I can't seem to get it correct, the brackets really confuse me. Which parts of the formula would I wrap the .pow within?
My attempt: =B2*(B3/12) / Math.pow( (1-(1+(B3/12)) , -B6) )
UPDATE:
Please see this Fiddle
Fiddle code:
var B2 = 500000; //£500,000
var B3 = 2.00; //2.00%
var B6 = 300; //Total number of payments
var original_formula = 'B2*(B3/12)/(1-(1+(B3/12))^-B6)';
var x = B2 * (B3 / 12) / Math.pow(1 - (1 + (B3 / 12)), -B6)
console.log(x);
//Expected/Excel result = 2,119.27
//Actual result = 2.9884337938456618e-229 <- what's going on here?
Have not tried this, but one problem is probably that you're wrapping the two arguments in Math.pow() with a set parentheses.
In your original formula, you wrap the base and exponent in parentheses to group them together:
(1 - (1 + (B3 / 12)) ^ -B6)
Math.pow() takes two arguments, the base, and the exponent:
Math.pow(base, exponent)
You can't use parentheses across two arguments in Javascript, and in fact you don't need to since the pow() function knows that the two arguments should be used together.
So instead of:
Math.pow((1 - (1 + (B3 / 12)), -B6))
I think that should be more like:
Math.pow(1 - (1 + (B3 / 12)), -B6)
=B2*(B3/12) / (1-(1+(B3/12)) ^ -B6)
is the same as
=B2*B3/12 / ( 1 - (1+B3/12) ^ -B6 )
With this reduced number of parantheses it is perhaps easier to see that the javascript implementation should be
= B2*B3/12 / ( 1 - Math.pow(1+B3/12, -B6) )
You also need to translate B3=2.00% into B3=2.00/100 or B3=0.02. Then the result is indeed 2119.2716932202998
var B2 = 500000; //£500,000
var B3 = 2.00; //2.00%
var B6 = 300; //Total number of payments
var original_formula = 'B2*(B3/12)/(1-(1+(B3/12))^-B6)';
B3 = B3/100 // 2.0% is 0.02 as number
var x = B2*B3/12 / (1 - Math.pow(1 + B3/12, -B6) )
var log = document.getElementById("log")
log.innerHTML += "x="+x;
<div id="log"></div>

want to create a fixed deposit calculator(quaterly) using javascript in joomla chronoforms

I am trying to display results after calculating fixed deposit maturity value based on compound interest formula. I am trying this with Joomla Chronoforms. Have also tried with Math.pow. Still not wrking.
jQuery(document).ready(function(jQ) {
jQ('#tenure_month').keyup( calc );
jQ('#cmpnd_anually').keyup( calcu );
var to_years;
function calc() {
to_years = jQ('#tenure_month').val();
to_years = parseFloat(to_years) / 12;
to_years = to_years.toFixed(1);
jQ('#years').val(to_years);
};
function calcu() {
var dep;
var rate_int;
var cmp_int;
dep = jQ('#deposit_amt').val();
dep = parseFloat(dep);
rate_int = parseFloat(jQ('#rate_int').val() / 400));
rate_int = rate_int.toFixed(1);
cmp_int = dep * (1 + rate_int) ^ 4 * t_years;
jQ('#cmpnd_anually').val(cmp_int);
};
});
But not getting output. Any suggestions?
Mostly you need to debug your code:
There is an extra ) in this line rate_int =
parseFloat(jQ('#rate_int').val() / 400));
t_years isn't defined in this line cmp_int = dep * (1 + rate_int) ^
4 * t_years;
and you are using jQ('#cmpnd_anually') both for input and output

Round number to nearest .5 decimal

I'm looking for an output of
4.658227848101266 = 4.5
4.052117263843648 = 4.0
the closest I've gotten is
rating = (Math.round(rating * 4) / 4).toFixed(1)
but with this the number 4.658227848101266 = 4.8???
(Math.round(rating * 2) / 2).toFixed(1)
It's rather simple, you should multiply that number by 2, then round it and then divide it by 2:
var roundHalf = function(n) {
return (Math.round(n*2)/2).toFixed(1);
};
This works for me! (Using the closest possible format to yours)
rating = (Math.round(rating * 2) / 2).toFixed(1)
So this answer helped me. Here is a little bit o magic added to it to handle rounding to .5 or integer. Notice that the *2 and /2 is switched to /.5 and *.5 compared to every other answer.
/*
* #param {Number} n - pass in any number
* #param {Number} scale - either pass in .5 or 1
*/
var superCoolRound = function(n,scale) {
return (Math.round(n / scale) * scale).toFixed(1);
};
This is kinda late. But for someone who wants to round down to whole number or 0.5, you can try this:
function roundDown(number) {
var decimalPart = number % 1;
if (decimalPart < 0.5)
return number - decimalPart;
else
return number - decimalPart + 0.5;}
Late to this party, but I thought I would throw in a nice answer using a syntax I saw elsewhere, just in case someone comes across this in the future.
const roundDown = decimalNumber => {
return decimalNumber % 1 >= 0.5 ? +`${~~decimalNumber}.5` : ~~decimalNumber;
}
Explanation:
decimalNumber % 1 leaves you with only the decimal places
The + converts the string representation of your constructed number into a float, for consistency
~~decimalNumber drops the decimal places, leaving you with an integer
I assume you want to format the number for output and not truncate the precision. In that case, use a DecimalFormat. For example:
DecimalFormat df = new DecimalFormat("#.#");
df.format(rating);

Trying to round an object value in javascript

I have seemingly a very simple little script...
function speedcomp(obj) {
obj.speedmile.value = 3600 / obj.timesec.value
}
function distcomp(obj) {
if (obj.speed.value == "")
obj.speed.value = ((1 * obj.distance.value) / obj.day.value) / 24;
else if (obj.distance.value == "")
obj.distance.value = distance.value;
else if (obj.day.value == "")
obj.day.value = ((1 * obj.distance.value) / obj.speed.value) / 24;
obj.hour.value = ((1 * obj.distance.value) / obj.speed.value);
}​
I have 4 input type text's with id's of distance, speed, day, and hour. When I put in a speed and distance and click a button who's onclick="distcomp(this.form)" it does the math for me nicely.
The issue I am having is trying to round the values for day and hour to the nearest 100th. Since I am not presetting the values I am finding my self struggling with Math.round and Math.floor. I believe the answer will be using Math.round but I could use some.
Thank you in advance.
You could just use toFixed:
var num = Math.random();
alert(num.toFixed(2));
There are some buggy implementations around IE 6, and javascript decimals aren't precise for some values so you might get unexpected results:
(0.595).toFixed(2) // 0.59 in Firefox, 0.60 in IE
If you use:
Math.round(num*100)/100
then you will not get the right padding (0.59 => 0.6 not 0.60). MDN has some other interesting snippets.
There seems to be a reasonable replacement for toFixed in answer to How to write a prototype for Number.toFixed in JavaScript?.
Edit
Here is a reasonable toFixed function, I'll keep testing to make sure it's reasonably ES5 compliant. For toFixed(0,2) it returns 0.00 whereas the spec says 0 but I think the former is more useful.
function toFixed(num, places) {
var m, s = '', t;
num = Number(num);
if (isNaN(num)) return 'NaN';
if (num < 0) {
s = '-';
num = num * -1;
}
m = Math.pow(10, places || 0);
num = String(Math.round(num * m) / m).split('.');
t = num[1] || '';
num[1] = t + (new Array(places - t.length + 1)).join('0');
return s + num.join('.');
};
Jasper's comment seems like a good solution:
(Math.round(.595*100)/100).toFixed(2);
though (0).toFixed(2) gives 0 (per EMCA-262) rather than the more useful 0.00, which is why the above avoids toFixed.
To round to the nearest 100th, multiply the number by 100, call Math.round() and then divide by 100 again.
num=210.653434343
Math.round(num*100)/100
210.65
To round to the 100s place, divide first, round, then multiply. You can also change 100 to any other place and it will work for that. (change 100 to 10 for 10s and 10ths place)

Seedable JavaScript random number generator

The JavaScript Math.random() function returns a random value between 0 and 1, automatically seeded based on the current time (similar to Java I believe). However, I don't think there's any way to set you own seed for it.
How can I make a random number generator that I can provide my own seed value for, so that I can have it produce a repeatable sequence of (pseudo)random numbers?
One option is http://davidbau.com/seedrandom which is a seedable RC4-based Math.random() drop-in replacement with nice properties.
If you don't need the seeding capability just use Math.random() and build helper functions around it (eg. randRange(start, end)).
I'm not sure what RNG you're using, but it's best to know and document it so you're aware of its characteristics and limitations.
Like Starkii said, Mersenne Twister is a good PRNG, but it isn't easy to implement. If you want to do it yourself try implementing a LCG - it's very easy, has decent randomness qualities (not as good as Mersenne Twister), and you can use some of the popular constants.
EDIT: consider the great options at this answer for short seedable RNG implementations, including an LCG option.
function RNG(seed) {
// LCG using GCC's constants
this.m = 0x80000000; // 2**31;
this.a = 1103515245;
this.c = 12345;
this.state = seed ? seed : Math.floor(Math.random() * (this.m - 1));
}
RNG.prototype.nextInt = function() {
this.state = (this.a * this.state + this.c) % this.m;
return this.state;
}
RNG.prototype.nextFloat = function() {
// returns in range [0,1]
return this.nextInt() / (this.m - 1);
}
RNG.prototype.nextRange = function(start, end) {
// returns in range [start, end): including start, excluding end
// can't modulu nextInt because of weak randomness in lower bits
var rangeSize = end - start;
var randomUnder1 = this.nextInt() / this.m;
return start + Math.floor(randomUnder1 * rangeSize);
}
RNG.prototype.choice = function(array) {
return array[this.nextRange(0, array.length)];
}
var rng = new RNG(20);
for (var i = 0; i < 10; i++)
console.log(rng.nextRange(10, 50));
var digits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
for (var i = 0; i < 10; i++)
console.log(rng.choice(digits));
If you want to be able to specify the seed, you just need to replace the calls to getSeconds() and getMinutes(). You could pass in an int and use half of it mod 60 for the seconds value and the other half modulo 60 to give you the other part.
That being said, this method looks like garbage. Doing proper random number generation is very hard. The obvious problem with this is that the random number seed is based on seconds and minutes. To guess the seed and recreate your stream of random numbers only requires trying 3600 different second and minute combinations. It also means that there are only 3600 different possible seeds. This is correctable, but I'd be suspicious of this RNG from the start.
If you want to use a better RNG, try the Mersenne Twister. It is a well tested and fairly robust RNG with a huge orbit and excellent performance.
EDIT: I really should be correct and refer to this as a Pseudo Random Number Generator or PRNG.
"Anyone who uses arithmetic methods to produce random numbers is in a state of sin."
--- John von Neumann
I use a JavaScript port of the Mersenne Twister:
https://gist.github.com/300494
It allows you to set the seed manually. Also, as mentioned in other answers, the Mersenne Twister is a really good PRNG.
The code you listed kind of looks like a Lehmer RNG. If this is the case, then 2147483647 is the largest 32-bit signed integer, 2147483647 is the largest 32-bit prime, and 48271 is a full-period multiplier that is used to generate the numbers.
If this is true, you could modify RandomNumberGenerator to take in an extra parameter seed, and then set this.seed to seed; but you'd have to be careful to make sure the seed would result in a good distribution of random numbers (Lehmer can be weird like that) -- but most seeds will be fine.
The following is a PRNG that may be fed a custom seed. Calling SeedRandom will return a random generator function. SeedRandom can be called with no arguments in order to seed the returned random function with the current time, or it can be called with either 1 or 2 non-negative inters as arguments in order to seed it with those integers. Due to float point accuracy seeding with only 1 value will only allow the generator to be initiated to one of 2^53 different states.
The returned random generator function takes 1 integer argument named limit, the limit must be in the range 1 to 4294965886, the function will return a number in the range 0 to limit-1.
function SeedRandom(state1,state2){
var mod1=4294967087
var mul1=65539
var mod2=4294965887
var mul2=65537
if(typeof state1!="number"){
state1=+new Date()
}
if(typeof state2!="number"){
state2=state1
}
state1=state1%(mod1-1)+1
state2=state2%(mod2-1)+1
function random(limit){
state1=(state1*mul1)%mod1
state2=(state2*mul2)%mod2
if(state1<limit && state2<limit && state1<mod1%limit && state2<mod2%limit){
return random(limit)
}
return (state1+state2)%limit
}
return random
}
Example use:
var generator1=SeedRandom() //Seed with current time
var randomVariable=generator1(7) //Generate one of the numbers [0,1,2,3,4,5,6]
var generator2=SeedRandom(42) //Seed with a specific seed
var fixedVariable=generator2(7) //First value of this generator will always be
//1 because of the specific seed.
This generator exhibit the following properties:
It has approximately 2^64 different possible inner states.
It has a period of approximately 2^63, plenty more than anyone will ever realistically need in a JavaScript program.
Due to the mod values being primes there is no simple pattern in the output, no matter the chosen limit. This is unlike some simpler PRNGs that exhibit some quite systematic patterns.
It discards some results in order to get a perfect distribution no matter the limit.
It is relatively slow, runs around 10 000 000 times per second on my machine.
Bonus: typescript version
If you program in Typescript, I adapted the Mersenne Twister implementation that was brought in Christoph Henkelmann's answer to this thread as a typescript class:
/**
* copied almost directly from Mersenne Twister implementation found in https://gist.github.com/banksean/300494
* all rights reserved to him.
*/
export class Random {
static N = 624;
static M = 397;
static MATRIX_A = 0x9908b0df;
/* constant vector a */
static UPPER_MASK = 0x80000000;
/* most significant w-r bits */
static LOWER_MASK = 0x7fffffff;
/* least significant r bits */
mt = new Array(Random.N);
/* the array for the state vector */
mti = Random.N + 1;
/* mti==N+1 means mt[N] is not initialized */
constructor(seed:number = null) {
if (seed == null) {
seed = new Date().getTime();
}
this.init_genrand(seed);
}
private init_genrand(s:number) {
this.mt[0] = s >>> 0;
for (this.mti = 1; this.mti < Random.N; this.mti++) {
var s = this.mt[this.mti - 1] ^ (this.mt[this.mti - 1] >>> 30);
this.mt[this.mti] = (((((s & 0xffff0000) >>> 16) * 1812433253) << 16) + (s & 0x0000ffff) * 1812433253)
+ this.mti;
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
/* In the previous versions, MSBs of the seed affect */
/* only MSBs of the array mt[]. */
/* 2002/01/09 modified by Makoto Matsumoto */
this.mt[this.mti] >>>= 0;
/* for >32 bit machines */
}
}
/**
* generates a random number on [0,0xffffffff]-interval
* #private
*/
private _nextInt32():number {
var y:number;
var mag01 = new Array(0x0, Random.MATRIX_A);
/* mag01[x] = x * MATRIX_A for x=0,1 */
if (this.mti >= Random.N) { /* generate N words at one time */
var kk:number;
if (this.mti == Random.N + 1) /* if init_genrand() has not been called, */
this.init_genrand(5489);
/* a default initial seed is used */
for (kk = 0; kk < Random.N - Random.M; kk++) {
y = (this.mt[kk] & Random.UPPER_MASK) | (this.mt[kk + 1] & Random.LOWER_MASK);
this.mt[kk] = this.mt[kk + Random.M] ^ (y >>> 1) ^ mag01[y & 0x1];
}
for (; kk < Random.N - 1; kk++) {
y = (this.mt[kk] & Random.UPPER_MASK) | (this.mt[kk + 1] & Random.LOWER_MASK);
this.mt[kk] = this.mt[kk + (Random.M - Random.N)] ^ (y >>> 1) ^ mag01[y & 0x1];
}
y = (this.mt[Random.N - 1] & Random.UPPER_MASK) | (this.mt[0] & Random.LOWER_MASK);
this.mt[Random.N - 1] = this.mt[Random.M - 1] ^ (y >>> 1) ^ mag01[y & 0x1];
this.mti = 0;
}
y = this.mt[this.mti++];
/* Tempering */
y ^= (y >>> 11);
y ^= (y << 7) & 0x9d2c5680;
y ^= (y << 15) & 0xefc60000;
y ^= (y >>> 18);
return y >>> 0;
}
/**
* generates an int32 pseudo random number
* #param range: an optional [from, to] range, if not specified the result will be in range [0,0xffffffff]
* #return {number}
*/
nextInt32(range:[number, number] = null):number {
var result = this._nextInt32();
if (range == null) {
return result;
}
return (result % (range[1] - range[0])) + range[0];
}
/**
* generates a random number on [0,0x7fffffff]-interval
*/
nextInt31():number {
return (this._nextInt32() >>> 1);
}
/**
* generates a random number on [0,1]-real-interval
*/
nextNumber():number {
return this._nextInt32() * (1.0 / 4294967295.0);
}
/**
* generates a random number on [0,1) with 53-bit resolution
*/
nextNumber53():number {
var a = this._nextInt32() >>> 5, b = this._nextInt32() >>> 6;
return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0);
}
}
you can than use it as follows:
var random = new Random(132);
random.nextInt32(); //return a pseudo random int32 number
random.nextInt32([10,20]); //return a pseudo random int in range [10,20]
random.nextNumber(); //return a a pseudo random number in range [0,1]
check the source for more methods.
Here is quite an effective but simple javascript PRNG function that I like to use:
// The seed is the base number that the function works off
// The modulo is the highest number that the function can return
function PRNG(seed, modulo) {
str = `${(2**31-1&Math.imul(48271,seed))/2**31}`
.split('')
.slice(-10)
.join('') % modulo
return str
}
I hope this is what you're looking for.
Thank you, #aaaaaaaaaaaa (Accepted Answer)
I really needed a good non-library solution (easier to embed)
so... i made this class to store the seed and allow a Unity-esque "Next" ... but kept the initial Integer based results
class randS {
constructor(seed=null) {
if(seed!=null) {
this.seed = seed;
} else {
this.seed = Date.now()%4645455524863;
}
this.next = this.SeedRandom(this.seed);
this.last = 0;
}
Init(seed=this.seed) {
if (seed = this.seed) {
this.next = this.SeedRandom(this.seed);
} else {
this.seed=seed;
this.next = this.SeedRandom(this.seed);
}
}
SeedRandom(state1,state2){
var mod1=4294967087;
var mod2=4294965887;
var mul1=65539;
var mul2=65537;
if(typeof state1!="number"){
state1=+new Date();
}
if(typeof state2!="number"){
state2=state1;
}
state1=state1%(mod1-1)+1;
state2=state2%(mod2-1)+1;
function random(limit){
state1=(state1*mul1)%mod1;
state2=(state2*mul2)%mod2;
if(state1<limit && state2<limit && state1<mod1%limit && state2<mod2%limit){
this.last = random;
return random(limit);
}
this.last = (state1+state2)%limit;
return (state1+state2)%limit;
}
this.last = random;
return random;
}
}
And then checked it with these... seems to work well with random (but queryable) seed value (a la Minecraft) and even stored the last value returned (if needed)
var rng = new randS(9005646549);
console.log(rng.next(20)+' '+rng.next(20)+' '+rng.next(20)+' '+rng.next(20)+' '+rng.next(20)+' '+rng.next(20)+' '+rng.next(20));
console.log(rng.next(20) + ' ' + rng.next(20) + ' ' + rng.last);
which should output (for everybody)
6 7 8 14 1 12 6
9 1 1
EDIT: I made the init() work if you ever needed to reseed, or were testing values (this was necessary in my context as well)
Note: This code was originally included in the question above. In the interests of keeping the question short and focused, I've moved it to this Community Wiki answer.
I found this code kicking around and it appears to work fine for getting a random number and then using the seed afterward but I'm not quite sure how the logic works (e.g. where the 2345678901, 48271 & 2147483647 numbers came from).
function nextRandomNumber(){
var hi = this.seed / this.Q;
var lo = this.seed % this.Q;
var test = this.A * lo - this.R * hi;
if(test > 0){
this.seed = test;
} else {
this.seed = test + this.M;
}
return (this.seed * this.oneOverM);
}
function RandomNumberGenerator(){
var d = new Date();
this.seed = 2345678901 + (d.getSeconds() * 0xFFFFFF) + (d.getMinutes() * 0xFFFF);
this.A = 48271;
this.M = 2147483647;
this.Q = this.M / this.A;
this.R = this.M % this.A;
this.oneOverM = 1.0 / this.M;
this.next = nextRandomNumber;
return this;
}
function createRandomNumber(Min, Max){
var rand = new RandomNumberGenerator();
return Math.round((Max-Min) * rand.next() + Min);
}
//Thus I can now do:
var letters = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
var numbers = ['1','2','3','4','5','6','7','8','9','10'];
var colors = ['red','orange','yellow','green','blue','indigo','violet'];
var first = letters[createRandomNumber(0, letters.length)];
var second = numbers[createRandomNumber(0, numbers.length)];
var third = colors[createRandomNumber(0, colors.length)];
alert("Today's show was brought to you by the letter: " + first + ", the number " + second + ", and the color " + third + "!");
/*
If I could pass my own seed into the createRandomNumber(min, max, seed);
function then I could reproduce a random output later if desired.
*/
OK, here's the solution I settled on.
First you create a seed value using the "newseed()" function. Then you pass the seed value to the "srandom()" function. Lastly, the "srandom()" function returns a pseudo random value between 0 and 1.
The crucial bit is that the seed value is stored inside an array. If it were simply an integer or float, the value would get overwritten each time the function were called, since the values of integers, floats, strings and so forth are stored directly in the stack versus just the pointers as in the case of arrays and other objects. Thus, it's possible for the value of the seed to remain persistent.
Finally, it is possible to define the "srandom()" function such that it is a method of the "Math" object, but I'll leave that up to you to figure out. ;)
Good luck!
JavaScript:
// Global variables used for the seeded random functions, below.
var seedobja = 1103515245
var seedobjc = 12345
var seedobjm = 4294967295 //0x100000000
// Creates a new seed for seeded functions such as srandom().
function newseed(seednum)
{
return [seednum]
}
// Works like Math.random(), except you provide your own seed as the first argument.
function srandom(seedobj)
{
seedobj[0] = (seedobj[0] * seedobja + seedobjc) % seedobjm
return seedobj[0] / (seedobjm - 1)
}
// Store some test values in variables.
var my_seed_value = newseed(230951)
var my_random_value_1 = srandom(my_seed_value)
var my_random_value_2 = srandom(my_seed_value)
var my_random_value_3 = srandom(my_seed_value)
// Print the values to console. Replace "WScript.Echo()" with "alert()" if inside a Web browser.
WScript.Echo(my_random_value_1)
WScript.Echo(my_random_value_2)
WScript.Echo(my_random_value_3)
Lua 4 (my personal target environment):
-- Global variables used for the seeded random functions, below.
seedobja = 1103515.245
seedobjc = 12345
seedobjm = 4294967.295 --0x100000000
-- Creates a new seed for seeded functions such as srandom().
function newseed(seednum)
return {seednum}
end
-- Works like random(), except you provide your own seed as the first argument.
function srandom(seedobj)
seedobj[1] = mod(seedobj[1] * seedobja + seedobjc, seedobjm)
return seedobj[1] / (seedobjm - 1)
end
-- Store some test values in variables.
my_seed_value = newseed(230951)
my_random_value_1 = srandom(my_seed_value)
my_random_value_2 = srandom(my_seed_value)
my_random_value_3 = srandom(my_seed_value)
-- Print the values to console.
print(my_random_value_1)
print(my_random_value_2)
print(my_random_value_3)

Categories

Resources