2014-10-11 88 views
5

我有生成OBJ-C 1D噪音这段代码,它的工作非常清楚:培林噪声发生器在斯威夫特

- (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); 
} 

现在我试图重现它在斯威夫特,但总是失败,并显示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并且种子为10,只是为了简化)

感谢您的帮助!

+0

你有没有想过改变这个方法接受一个浮动,而不是一个int作为参数? – Kat 2015-08-13 16:41:13

回答

8

如果您的计算结果 不能表示为Int,则会发生“算术溢出”,导致异常。与(Objective-)C不同,在Swift中添加和相乘整数不会“绕回” 或“截断”,但如果结果不符合数据类型会导致错误。

但是你可以使用雨燕"overflow operators"&*&+相反,它总是截断结果:

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) 
} 
+0

太棒了!我不知道他们为此创造了新的运营商。非常感谢! – Endanke 2014-10-11 11:30:40

+0

@ ha100:感谢您更新链接! – 2017-08-03 19:19:19

+0

很高兴。无论如何,你节省了我的一天 – ha100 2017-08-03 19:29:40