Implementing noise function in python from C code


I want to play around with procedural content generation algorithms, and decided to start with noises (Perlin, value, etc)

For that, I want have a generic n-dimensional noise function. For that I wrote a function that returns a noise generation function of the given dimension:

small_primes = [1, 83, 97, 233, 61, 127]

def get_noise_function(dimension, random_seed=None):
    primes_list = list(small_primes)
    if dimension > len(primes_list):
        primes_list = primes_list * (dimension / len(primes_list))
    rand = random.Random()
    if random_seed:
    # random.shuffle(primes_list)

    def noise_func(*args):
        if len(args) < dimension:
            # throw something
            return None
        n = [a*b for a, b in zip(args, primes_list)]
        n = sum(n)
        #n = (n << 13) ** n
        n = (n << 13) ^ n
        nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff
        return 1.0 - (nn / 1073741824.0)

    return noise_func

The, problem, I believe, is with the calculations. I based my code on these two articles:

Example of one of my tests:

f1 = get_noise_function(1, 10)
print f1(1)
print f1(2)
print f1(3)
print f1(1)

It always returns -0.281790983863, even on higher dimensions and different seeds.

The problem, I believe, is that in C/C++ there is overflow is some of the calculations, and everything works. In python, it just calculates a gigantic number.

How can I correct this or, if possible, how can I generate a pseudo-random function that, after being seeded, for a certain input always returns the same value.

[EDIT] Fixed the code. Now it works.

asked on Stack Overflow Oct 8, 2013 by Vasco Correia • edited Apr 18, 2019 by genpfault

1 Answer


Where the referenced code from Hugo Elias has:

 x = (x<<13) ^ x

you have:

n = (n << 13) ** n

I believe Elias is doing bitwise xor, while you're effectively raising 8192*n to the power of n. That gives you a huge value. Then

nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff

takes that gigantic n and makes it even bigger, until you finally throw away everything but the last 31 bits. It doesn't make much sense ;-)

Try changing your code to:

n = (n << 13) ^ n

and see whether that helps.

answered on Stack Overflow Oct 8, 2013 by Tim Peters

User contributions licensed under CC BY-SA 3.0