Javascript - will this noise function work? - javascript

I have the following deterministic noise function which I've been using in a C# and C++ terrain generator for a while:
float GridNoise(int x, int z, int seed)
{
int n = (1619*x + 31337*z + 1013*seed) & 0x7fffffff;
n = (n >> 13) ^ n;
return 1 - ((n*(n*n*60493 + 19990303) + 1376312589) & 0x7fffffff)/(float)1073741824;
}
It returns a 'random' float between 1 and -1 for any integer x/z coordinates I enter (plus there's a seed so I can generate different terrains). I tried implementing the same function in Javascript, but the results aren't as expected. For small values, it seems OK but as I use larger values (of the order of ~10000) the results are less and less random and eventually all it returns is 1.
You can see it working correctly in C# here, and the incorrect JS results for the same input here.
I suspect it's something to do with JS variables not being strict integers, but can anyone shed more light? Does anyone have a similarly simple deterministic function I could use in JS if this doesn't work?

The underlying problem is, in javascript, there's no integers - so all mathematical functions are done using Number (52bit precision float)
In c#, if you're using longs, then any overflows are just discarded
In javascript, you need to handle this yourself
There's a numeric format is coming to browsers that will help, but it's not here yet - BigInt ... it's in chrome/opera and behind a flag in firefox (desktop, not android)
(no word on Edge (dead anyway) or Safari (the new IE) - and of course, IE will never get them)
The best I can come up with using BigInt is
function gridNoise(x, z, seed) {
var n = (1619 * x + 31337 * z + 1013 * seed) & 0x7fffffff;
n = BigInt((n >> 13) ^ n);
n = n * (n * n * 60493n + 19990303n) + 1376312589n;
n = parseInt(n.toString(2).slice(-31), 2);
return 1 - n / 1073741824;
}
function test() {
for (var i = 10000; i < 11000; i++) {
console.log(gridNoise(0, 0, i));
}
}
test();
Note, the 60493n is BigInt notation
There are "big integer" libraries you could use in the interim though - https://github.com/peterolson/BigInteger.js
The following doesn't work and never will ... because a 32bit x 32bit == 64bit ... so you'll lose bits already
I misread the code and though n was only 19 bits (because of the >>13)
If you limit the result of n * n * 60493 to 32bit, (actually, I made it 31bit ... so .. anyway it seems to work OK
function gridNoise(x, z, seed) {
var n = (1619 * x + 31337 * z + 1013 * seed) & 0x7fffffff;
n = (n >> 13) ^ n;
return 1 - ((n * (n * n * 60493 & 0x7fffffff + 19990303) + 1376312589) & 0x7fffffff) / 1073741824;
}
this also works
return 1 - ((n*(n*n*60493 | 0 + 19990303) + 1376312589) & 0x7fffffff)/1073741824;
That limits the interim result to 32 bit which may or may not be "accurate"
You may need to play around with it if you want to duplicate exactly what c# produces

I'm afraid your code is exceeding the maximum size limit for integers. As soon as that happens, it's returning 1 because the calculation ((n*(n*n*60493 + 19990303) + 1376312589) & 0x7fffffff)/1073741824 will always be 0 - thus 1 - 0 = 1

To understand whats going on here, one has to examine the JavaScripts number type. It is basically a 53bit integer, that gets left/right shifted using another 11bit integer, resulting in a 64bit number. Therefore if you have a calculation that would result in a 54bit integer, it just takes the upper 53bits, and shifts them left by 1. Now if you do bitwise math on numbers, it will take the lower 32bits. Therefore if an integer is bigger than 84bits, doing bitwise shifting on it will always result in 0. Numbers bigger than 32bits will therefore tend to 0 in JS when doing bitwise operations, while C# always takes the lower 32bits, and therefore the result will be accurate for those 32bits (but larger numbers cannot be represented).
(2 + 2 ** 53) & (2 + 2 ** 53) // 2
(2 + 2 ** 54) & (2 + 2 ** 54) // 0

Edit (sorry for the poor previous answer):
As others stated before is the problem related too your values which are exceeding the size of JS Number.
If you have the code working in C#, it might be advisable to offload the functionality to an ASP.NET backend which will handle the calculation an forward the result via some sort of API

Related

Modulo of exponentiation by square in Javascript not working correctly?

For the past several hours I've been trying to implement Exponentiation by squaring in Javascript. Basically I've been trying to apply the Fermat Little Theorem to solve the modular multiplicative inverse. It seems like it should be straight forward yet I'm getting incorrect results:
const MAX = 10**9 + 7
const inv2 = expBySquare(2, MAX-2)
// inv2 should be 500000004 but is 437533240
function expBySquare(x, n) {
if (n < 0) throw 'error'
if (n === 0) return 1
if (n === 1) return x
if (n % 2 === 0) return expBySquare((x * x) % MAX, n / 2) % MAX
return (x * expBySquare((x * x) % MAX, (n - 1) / 2)) % MAX
}
I've just tried to implement the algorithm in C https://onlinegdb.com/H1tsx4TY7 and it worked without problems. I knew that I should expected problems with overflows in JS but I think that it can handle the numbers since the modulo is used in all the weak points.
I knew that I should expected problems with overflows in JS but I think that it can handle the numbers since the modulo is used in all the weak points.
JavaScript doesn't actually have a distinct "integer" type with "overflow"; rather, it just has a "number" type, whose values are double-precision floating-point numbers and are subject to roundoff error. So even if the value of x * x is representable as a 64-bit integer, it may not be exactly representable as a JavaScript number. JavaScript numbers can exactly represent any integer in the range [−(253 −1), 253 −1] — see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER — but your calculation involves values outside that range.
To see for yourself that you're venturing outside that range, you can insert this:
if (x * x > Number.MAX_SAFE_INTEGER)
throw 'error: ' + x + ' * ' + x + ' is ' + (x * x);
You will see error: 294967268 * 294967268 is 87005689191383820 even though 294,967,268 × 294,967,268 is actually 8,7005,689,191,383,824.
To fix this, you either need a smaller value of MAX (to ensure that MAX * MAX <= Number.MAX_SAFE_INTEGER), or to use a (partial) big-integer library to perform integer arithmetic on the large values you're using.
JavaScript numbers always use a 64-bit floating point format. Hence, you can only work with a mantissa of 52 bits, which give you effective 53 bits. The intermediate values in your scenario exceed those, which will introduce rounding errors. The first time this happens is the squaring of 279,632,277. This should be 78,194,210,340,204,729 (57 bit) but gets rounded to 78,194,210,340,204,730.

Modulo of 24 digit long integer?

I need to calculate the modulo of a 24 digit long integer (IBAN checksum) but JS calculates wrong.
e.g.:
700901001234567890131400 % 97 = 90
but in JS (V8) it's 38.
How can I calculate the modulo in JS
I think the document you're linking to already says what you should do:
If the application software in use does not provide the ability to handle integers of this size, the modulo operation can be performed in a piece-wise manner.
Piece-wise calculation D mod 97 can be done in many ways. One such way is as follows:
Starting from the leftmost digit of D, construct a number using the first 9 digits and call it N.[Note 3]
Calculate N mod 97.
Construct a new 9-digit N by concatenating above result (step 2) with the next 7 digits of D. If there are fewer than 7 digits remaining in D but at least one, then construct a new N, which will have less than 9 digits, from the above result (step 2) followed by the remaining digits of D
Repeat steps 2–3 until all the digits of D have been processed
The result of the final calculation in step 2 will be D mod 97 = N mod 97.
It might be harder than one can think.
It's quite tricky to ensure javascript handle number as integer (it often store them as float, but not always).
Others already made libraries to handle IBAN check in JS.
Take a look at https://github.com/arhs/iban.js for instance.
The largest number that can be represented in javascript is 2^53 - 1. They are 64-bit floating point values. So the largest number is 9007199254740991.
A number greater than 9007199254740991 can not be caclcuted in normal way. So, to find the modulo of such large number you have to break it into pieces.
eg. 700901001234567890131400 can be broken into 700901001234567 and 890131400.
First find the modulo of 700901001234567.
700901001234567 % 97 = 13
Now join 13 infront of second number 13890131400 and find the modulo of this number
13890131400 % 97 = 90
I came across this problem recently and this looks like what is solvable with Horner's method [https://en.wikipedia.org/wiki/Horner%27s_method]
/**
* str is numeric.
* MOD=97 is our use case
* #return: an integer 0<=x<=97
**/
int getMod(String str, int MOD) {
int remainder = 0;
for(Character c : str.toCharArray()) {
int value = Character.getNumericValue(c);
remainder = 10*remainder + value;
remainder %= MOD;
}
return remainder;
}
Unless I don't fully understand the problem, the code above should work.

My chip8 implementation according to specification is different than open source code on internet. Need a clarification

I am working on CHIP8 implementation and I am reading
Cowgod's
Chip-8
Technical Reference v1.0
http://web.archive.org/web/20130401182240/http://devernay.free.fr/hacks/chip8/C8TECH10.HTM#3.0
as a reference. I am sure this is a percise specification because it was recommended by several blogs that talks about CHIP8 as well. My question is, I have implemented my opcode for handling a code "7xkk"
7xkk - ADD Vx, byte
Set Vx = Vx + kk.
Adds the value kk to the value of register Vx, then stores the result in Vx.
And this is my code
case 0x7:
log(this.logging, "0x7xkk: Setting Vx = Vx + kk.");
var result = this.registers.V[(opcode & 0x0F00) >> 8] + (opcode & 0x00FF);
this.registers.V[(opcode & 0x0F00) >> 8] = result;
break;
but other open source CHIP8 has a completely different implementation of it
case 0x7000:
// Set Vx = Vx + kk.
this.register[vX] += opcode & 0x00FF;
if(this.register[vX] > 255){
this.register[vX] -= 256;
}
break;
//This person checks if Vx is bigger than 255 as well, which is not described in the specificaiton.
link- https://github.com/loktar00/chip8/blob/master/chip8.js#L181
and a C++ implementation I have found online
case 0x7: {
V[opCode2] = (char)((V[opCode2] + opCode & 0x00FF) & 0x00FF);
IP = IP + 2;
break;
}
//This person adds "opCode & 0x00FF" and apply and operation with "0x00FF" as well.
I am confused if I am looking at a specification that is too old or I am doing it correctly.
Chip-8 registers only contain a single 8-bit byte. A single byte can only hold values between 0 and 255 inclusive.
If an operation gives you a value which is outside the range of an 8-bit byte, you need to only preserve the lower 8 bits. That's what both of those implementations are doing, although in slightly different ways: the Javascript implementation explicitly checks for values greater than 255, while the C++ implementation simply discards any extra bits (that's the & 0x00FF at the end).
Your implementation is incorrect because you do not take this into account: if V[0] contains the value 255 and you have the opcode 0x7001 (add 1 to register 0), then your implementation will give 256, which cannot be stored in an 8-bit byte - the correct value is 0, which is the lower 8 bits of 256. This would, for example, cause problems for opcode 0xB, which takes V[0] as a jump offset, since it would jump much further than it was supposed to.

Next odd number in javascript

To find the next odd number for an input the following code is being used:
a=5.4; // Input
b=Math.ceil(a); // Required to turn input to whole number
b=b+(((b % 2)-1)*-1); // Gives 7
The ceil rounding function is required.
Is this safe and is there a more compact way to do this?
EDIT: When the input is already an odd whole number then nothing happens. For example 5.0 will return 5
How about just
b += b % 2 ^ 1;
The remainder after dividing by 2 will always be 0 or 1, so the ^ operator (exclusive-OR) flips it to the opposite.
(Also, (b & 1) ^ 1 would work too. Oh, I guess b = b ^ 1 would work for positive integers, but it'd be problematic for big integers.)
At the question author's request:
The most compact way to achieve it is
b = Math.ceil(a) | 1;
First use ceil() to obtain the smallest integer not smaller than a, then obtain the smallest odd integer not smaller than ceil(a) by doing a bitwise or with 1 to ensure the last bit is set without changing anything else.
To obtain the smallest odd integer strictly larger than a, use
b = Math.floor(a+1) | 1;
Caveats:
Bit-operators operate on signed 32-bit integers in Javascript, so the value of a must be smaller than or equal to 2^31-1, resp. strictly smaller for the second. Also, a must be larger than -2^31-1.
If the representation of signed integers is not two's complement, but ones' complement or sign-and-magnitude (I don't know whether Javascript allows that, Java doesn't, but it's a possibility in C), the value of a must be larger than -1 -- the result of Math.ceil(a) resp. Math.floor(a+1) must be nonnegative.
Not really shorter, but this is more legible:
a=5.4;
b=Math.ceil(a);
b = b % 2 ? b : b + 1;
Try this:
a = 5.4
b = Math.ceil(a)
b = b%2 == 0 ? b+1 : b
y = Math.ceil((x - 1)/2)*2 + 1
Execute fn on http://www.intmath.com/functions-and-graphs/graphs-using-jsxgraph.php
Without Math.ceil() it can be done so:
b = a + a % 2 | 0 + 1;
NB. I consider next odd number of 5.0 as 7.

Can someone translate this simple function into Javascript?

I'm reading a tutorial on Perlin Noise, and I came across this function:
function IntNoise(32-bit integer: x)
x = (x<<13) ^ x;
return ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & 7fffffff) / 1073741824.0);
end IntNoise function
While I do understand some parts of it, I really don't get what are (x<<13) and & 7fffffff supposed to mean (I see that it is a hex number, but what does it do?). Can someone help me translate this into JS? Also, normal integers are 32 bit in JS, on 32 bit computers, right?
It should work in JavaScript with minimal modifications:
function IntNoise(x) {
x = (x << 13) ^ x;
return (1 - ((x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824);
}
The << operator is a bitwise left-shift, so << 13 means shift the number 13 bits to the left.
The & operator is a bitwise AND. Doing & 0x7fffffff on a signed 32-bit integer masks out the sign bit, ensuring that the result is always a positive number (or zero).
The way that JavaScript deals with numbers is a bit quirky, to say the least. All numbers are usually represented as IEEE-754 doubles, but... once you start using bitwise operators on a number then JavaScript will treat the operands as signed 32-bit integers for the duration of that calculation.
Here's a good explanation of how JavaScript deals with bitwise operations:
Bitwise Operators
x<<13 means shift x 13 steps to left (bitwise).
Furthermore a<<b is equivalent to a*2^b.
& 7ffffff means bitwise AND of leftside with 7FFFFFFF.
If you take a look at the bit pattern of 7FFFFFFF you will notice that the bit 32 is 0 and the rest of the bits are 1. This means that you will mask out bit 0-30 and drop bit 31.

Categories

Resources