I am quite new to the wondrous world of "Procedural Textures", and I am trying to create a double precission perlin noise algorithm.
![Noise][1]
 I am almost done with it except for the fact that the coordinates seem to be off, any idea what I've done wrong? Here's the code: 
```cpp

public static class Noise {
 static int[] p = new int[Convert.ToInt32(Math.Pow(2,16))];
 public static vector2dDouble v1i;
 public static vector2dDouble v2i;
 public static vector2dDouble v3i;
 public static vector2dDouble v4i;

 public static double[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, float scale, int octaves, float persistance, float lacunarity, Vector3 offset) {
 double[,] noiseMap = new double[mapWidth, mapHeight];

 System.Random prng = new System.Random(seed);
 Vector2[] octaveOffsets = new Vector2[octaves];
 for (int i = 0; i < octaves; i++) {
 float offsetX = prng.Next(-100000, 100000) + offset.x;
 float offsetY = prng.Next(-100000, 100000) + offset.z;
 octaveOffsets[i] = new Vector2(offsetX, offsetY);
 }

 if (scale <= 0) {
 scale = 0.0001f;
 }

 float maxNoiseHeight = float.MinValue;
 float minNoiseHeight = float.MaxValue;

 float halfWidth = mapWidth / 2f;
 float halfHeight = mapHeight / 2f;

 for (int y = 0; y < mapHeight; y++) {
 for (int x = 0; x < mapWidth; x++) {

 float amplitude = 1;
 float frequency = 1;
 double noiseHeight = 0;

 for (int i = 0; i < octaves; i++) {
 double sampleX = (double)(x - halfWidth) / scale * frequency + octaveOffsets[i].x + 0.001;
 double sampleY = (double)(y - halfHeight) / scale * frequency + octaveOffsets[i].y + 0.001;

 double perlinValue = Noise2d(sampleX, sampleY);
 noiseHeight += perlinValue * amplitude;
 //Debug.Log(perlinValue);


 amplitude *= persistance;
 frequency *= lacunarity;
 }

 if (noiseHeight > maxNoiseHeight) {
 maxNoiseHeight = (float)noiseHeight;
 }
 else if (noiseHeight < minNoiseHeight) {
 minNoiseHeight = (float)noiseHeight;
 }
 noiseMap[x, y] = noiseHeight;
 }
 }

 for (int y = 0; y < noiseMap.GetLength(1); y++) {
 for (int x = 0; x < noiseMap.GetLength(0); x++) {
 noiseMap[x, y] = (double)Mathf.InverseLerp(minNoiseHeight, maxNoiseHeight, (float)noiseMap[x, y]);
 }
 }

[![enter image description here][1]][1]
 return noiseMap;
 }

 public static void init(int seed) {
 createGradients(p, seed);
 }

 public static int[] createGradients(int[] p, int seed) {
 System.Random prng = new System.Random(seed);
 for (int i = 0; i < p.GetLength(0) / 2; i++) {
 p[i] = prng.Next(0, 256);
 p[i + ((int)p.GetLength(0) / 2)] = p[i];
 }

 return p;
 }

 static vector2dDouble generateGradient(int val) {
 int hash = val & 3;
 switch (hash) {
 case 0:
 return new vector2dDouble(1.0, 1.0);
 case 1:
 return new vector2dDouble(-1.0, 1.0);
 case 2:
 return new vector2dDouble(-1.0, -1.0);
 case 3:
 return new vector2dDouble(1.0, -1.0);
 default: return new vector2dDouble(0, 0);
 }
 }

 static double Noise2d(double x, double y) {

 int ix = Convert.ToInt32(Math.Floor(x)) & (p.GetLength(0) / 2 - 1);
 int iy = Convert.ToInt32(Math.Floor(y)) & (p.GetLength(0) / 2 - 1);
 

 x -= Math.Floor(x);
 y -= Math.Floor(y);

 vector2dDouble v1 = new vector2dDouble(x - 1, y),
 v2 = new vector2dDouble(x - 1, y - 1),
 v3 = new vector2dDouble(x, y), 
 v4 = new vector2dDouble(x, y - 1);

 int g1 = p[p[ix + 1] + iy + 1],
 g2 = p[p[ix] + iy + 1],
 g3 = p[p[ix + 1] + iy], 
 g4 = p[p[ix] + iy];

 double u = fade(x);
 double v = fade(y);

 double f1 = v1.dot(generateGradient(g1)), 
 f2 = v2.dot(generateGradient(g2)), 
 f3 = v3.dot(generateGradient(g3)), 
 f4 = v4.dot(generateGradient(g4));


 return lerp(u, lerp(v, f2, f4), lerp(v ,f1, f3));
 }

 static double lerp(double t, double argc, double argv) { return argc + t * (argv - argc); }

 static double fade(double t) { return t * t * t * (t * (t * 6 - 15) + 10); }
}

[System.Serializable]
public struct vector2dDouble {
 public double x, y;

 public vector2dDouble(double argx, double argy) {
 x = argx;
 y = argy;
 }

 public double dot(vector2dDouble argc) {
 argc.x *= x;
 argc.y *= y;

 return argc.x + argc.y;
 }

 public void print() {
 Debug.Log(x + "," + y);
 }
}

```


 [1]: https://i.sstatic.net/OeGH8.jpg