私はかなり奇妙なバグに出会っています。次の小さなコードは、かなり単純な数式を使用しています。ProGuardが誤った計算をする可能性があります
protected double C_n_k(int n, int k)
{
if(k<0 || k>n)
return 0;
double s=1;
for(int i=1;i<=k;i++)
s=s*(n+1-i)/i;
return s;
}
編集 ProGuardのを使用すると、それはいくつかのデバイス上で間違って行くことができます。 HTC OneのAndroid 4.1.1ビルド3.16.401.8で確認しましたが、電子メールで判断すると、Android 4+を搭載した携帯電話が多く影響を受けています。それらの一部(Galaxy S3)では、アメリカのオペレーターブランドの携帯電話が影響を受けますが、国際版は影響を受けません。多くの電話は影響を受けません。
以下は、1 < = n < 25および0 < = k < = nのC(n、k)を計算するアクティビティコードです。上記のデバイスでは、最初のセッションで正しい結果が得られますが、その後の起動では、毎回違う位置に不正な結果が表示されます。
はどのようにそれができる:
私は3つの質問がありますか? ProGuardが何かを間違えたとしても、デバイスとセッションの間で一貫した計算が行われるはずです。
どうすれば避けることができますか?この場合、
double
をlong
に置き換えることはわかりますが、普遍的な方法ではありません。double
を使用して削除するか、難読化されていないバージョンをリリースすることは問題になりません。影響を受けるAndroidのバージョンは何ですか?私はゲームでそれを固定して、非常に速かったので、私はちょうど多くの選手がそれを見ていることを知っている、と時々私は計算に間違いを見るので、少なくともほとんど、問題外であるアンドロイド4.0
オーバーフローしていましたC(3,3)=3/1*2/2*1/3
。通常、間違った番号はC(10、...)のどこかで始まり、電話が "忘れて"いくつかの部門を作るように見えます。
私のSDKツールは22.3(最新)で、EclipseとIntelliJ IDEAの両方で作成されたビルドで見ました。
アクティビティコード:
package com.karmangames.mathtest;
import android.app.Activity;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.widget.TextView;
public class MathTestActivity extends Activity
{
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String s="";
for(int n=0;n<=25;n++)
for(int k=0;k<=n;k++)
{
double v=C_n_k_double(n,k);
s+="C("+n+","+k+")="+v+(v==C_n_k_long(n,k) ? "" : " Correct is "+C_n_k_long(n,k))+"\n";
if(k==n)
s+="\n";
}
System.out.println(s);
((TextView)findViewById(R.id.text)).setText(s);
((TextView)findViewById(R.id.text)).setMovementMethod(new ScrollingMovementMethod());
}
protected double C_n_k_double(int n, int k)
{
if(k<0 || k>n)
return 0;
//C_n^k
double s=1;
for(int i=1;i<=k;i++)
s=s*(n+1-i)/i;
return s;
}
protected double C_n_k_long(int n, int k)
{
if(k<0 || k>n)
return 0;
//C_n^k
long s=1;
for(int i=1;i<=k;i++)
s=s*(n+1-i)/i;
return (double)s;
}
}
main.xml:間違った計算結果(それは私がそれをしようとするたびに違う、覚えておいてください)
C(0,0)=1.0
C(1,0)=1.0
C(1,1)=1.0
C(2,0)=1.0
C(2,1)=2.0
C(2,2)=1.0
C(3,0)=1.0
C(3,1)=3.0
C(3,2)=3.0
C(3,3)=1.0
C(4,0)=1.0
C(4,1)=4.0
C(4,2)=6.0
C(4,3)=4.0
C(4,4)=1.0
C(5,0)=1.0
C(5,1)=5.0
C(5,2)=10.0
C(5,3)=10.0
C(5,4)=30.0 Correct is 5.0
C(5,5)=1.0
C(6,0)=1.0
C(6,1)=6.0
C(6,2)=15.0
C(6,3)=40.0 Correct is 20.0
C(6,4)=90.0 Correct is 15.0
C(6,5)=144.0 Correct is 6.0
C(6,6)=120.0 Correct is 1.0
C(7,0)=1.0
C(7,1)=7.0
C(7,2)=21.0
C(7,3)=35.0
C(7,4)=105.0 Correct is 35.0
C(7,5)=504.0 Correct is 21.0
C(7,6)=840.0 Correct is 7.0
C(7,7)=720.0 Correct is 1.0
C(8,0)=1.0
C(8,1)=8.0
C(8,2)=28.0
C(8,3)=112.0 Correct is 56.0
C(8,4)=70.0
C(8,5)=1344.0 Correct is 56.0
C(8,6)=3360.0 Correct is 28.0
C(8,7)=5760.0 Correct is 8.0
C(8,8)=5040.0 Correct is 1.0
C(9,0)=1.0
C(9,1)=9.0
C(9,2)=36.0
C(9,3)=168.0 Correct is 84.0
C(9,4)=756.0 Correct is 126.0
C(9,5)=3024.0 Correct is 126.0
C(9,6)=10080.0 Correct is 84.0
C(9,7)=25920.0 Correct is 36.0
C(9,8)=45360.0 Correct is 9.0
C(9,9)=40320.0 Correct is 1.0
C(10,0)=1.0
C(10,1)=10.0
C(10,2)=45.0
C(10,3)=120.0
C(10,4)=210.0
C(10,5)=252.0
C(10,6)=25200.0 Correct is 210.0
C(10,7)=120.0
C(10,8)=315.0 Correct is 45.0
C(10,9)=16800.0 Correct is 10.0
C(10,10)=1.0
ほとんど聞こえません。そのループで 's'の各値を記録しようとしましたが、計算の仕方が分かりませんでしたか? – zapl
「正しいですか?」どちらか? – DoubleDouble
FWIW、数学では、C(12,4)= 495です。 – rgettman