Генератор шума Perlin в Swift

У меня есть этот код для генерации 1D-шума в obj-c, он отлично работает:

- (float)makeNoise1D:(int)x {
    x = (x >> 13) ^ x;
    x = (x * (x * x * (int)_seed + 19990303) + 1376312589) & RAND_MAX;
    return ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & RAND_MAX) / 1073741824.0);
}

Теперь я пытаюсь воспроизвести его в Swift, но он всегда терпит неудачу и по возвращении показывает EXEC_BAD_INSTRUCTION. Вот как это выглядит сейчас, мне пришлось выплюнуть финальное выражение, но я почти уверен, что проблема не в этом.

func makeNoise1D(var x : Int) -> Float{
    x = (x >> 13) ^ x;
    x = (x * (x * x * seed! + 19990303) + 1376312589) & 0x7fffffff
    var inner = (x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff
    return ( 1.0 - ( Float(inner) ) / 1073741824.0)
}

Я уже перепробовал много разных приведения и разбиения на подвыражения, но все равно не получается. Единственное, что я понял, что первая и последняя строчка работают. (В большинстве моих тестов x было установлено на 20, а seed на 10, просто для простоты)

Спасибо за помощь!


person Endanke    schedule 11.10.2014    source источник
comment
Вы не думали изменить этот метод, чтобы он принимал в качестве параметра Float вместо Int?   -  person Kat    schedule 13.08.2015


Ответы (1)


Исключение вызвано «арифметическим переполнением», которое возникает, если результат одного из ваших вычислений не может быть представлен как Int.

В отличие от (Objective-)C, сложение и умножение целых чисел в Swift не «зацикливается» или «усекается», а вызывает ошибку, если результат не соответствует типу данных.

Но вы можете использовать Swift "операторы переполнения" вместо этого &* и &+, которые всегда обрезают результат:

func makeNoise1D(x : Int) -> Float{
    var x = x
    x = (x >> 13) ^ x;
    x = (x &* (x &* x &* seed! &+ 19990303) &+ 1376312589) & 0x7fffffff
    let inner = (x &* (x &* x &* 15731 &+ 789221) &+ 1376312589) & 0x7fffffff
    return ( 1.0 - ( Float(inner) ) / 1073741824.0)
}
person Martin R    schedule 11.10.2014
comment
Большой! Я понятия не имел, что они сделали новых операторов для этого. Большое спасибо! - person Endanke; 11.10.2014
comment
@ ha100: Спасибо за обновление ссылок! - person Martin R; 03.08.2017
comment
с удовольствием. ты все равно спас мой день - person ha100; 03.08.2017