2014-10-11 47 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