2015-11-17 14 views
5

は、以下の単純な分割を考慮してください制御分割精度

A=8.868; 
A/0.1 
ans = 
    88.679999999999993 

これは、浮動小数点精度に起因し、小さなミスが生じます。これが起こらないようにする方法はありますか?基本的に私がやっているのは、MATLABの許容数字の最大数に近づかないうちに、カンマを1ポジションだけシフトさせることです。彼らは唯一のゼロであるよう

A/0.1 
ans = 
    88.68 

後続ゼロ限り、無懸念される、と14桁目かそこらで、いくつかの番号が含まれていない:

私はその結果を取得したいと思います。象徴的な数学を使用して

R = (randi([8659 49847],[1e3 1]))/1e3; 
xmin = min(R); 
el = 0.1; 
step = 1/el; 
tmp1=xmin/el; 
tmp2=round(tmp1); 
tmp3=round(tmp2*el,3); 

tmp3 = 
    8.699999999999999 
+0

ちょっと好奇心から:なぜそのように?なぜ10倍にならないの? –

+0

@AnderBiguriこれは、私の場合、グリッドサイズ(センチメートル)です。 0.25,0.12、または顧客が望むものであれば何でもよい。 – Adriaan

+0

@AnderBiguri 'A * 10'もこの場合不正確です... – Dan

答えて

6

、あなたが正確な結果を得ることができます:

興味深いことに、この問題もN桁に丸めたときにポップアップする

x=sym('8.868')/sym('.1') 
+1

これはスピードの点でどのように機能しますか?私は800Mのデータポイントを持っているので、スピードは重要な問題です。 – Adriaan

+2

シンボリック数学は非常に遅く、おそらくこのようなデータサイズでは不可能です。 – Daniel

5

スロープがどこにあるかあなたはいつもfixed point算術演算を使用することができます10の倍数に10を乗じると、不正確さはありません。 Matlabでは、使用することができますFixed Point Toolbox

編集:あなたのコメントに続いて - それは0.05になるように設定されているようです。

+0

[私のコメント](http://stackoverflow.com/questions/33754807/controlling-division-precision#comment55277249_33754807)で指摘したように、勾配は常に10の倍数になるとは限りません。 – Adriaan

+0

@Adriaan、あなたは見つけることができますか勾配は何の共通倍数ですか?それ以外の場合は、常に無限精度の数学を使用できます。 –

+0

私のデータはミリメートル精度のデータ、つまり3桁で、X cmのグリッドでビンしたい。ここでXは顧客が必要とする解像度で決まる。通常、Xは0.1,0.25、または0.5mであり、データを丸める必要があります。 – Adriaan

3

数値を整数の部分で表すことができます。限り、あなたはfloatに変換しないように、あなたは精度を失うことはありません。

A = 8.868; 
div = 0.1; 
[N1,D1] = rat(A); 
[N2,D2] = rat(div); 
% divide A by div: 
N = N1 * D2; 
D = N2 * D1; 

もちろん、あなたの番号は、他の回答/コメントで述べたように、そもそも正確ではないかもしれません。分数への変換は近似を導入することもできますが、扱う数値とtolのパラメータはratに依存します。

+1

このアイデアは実装されています[ここ](http://stackoverflow.com/a/20873563/2732801) – Daniel

4

この回答は私の場合完全に掲載されています。


私はuniqueの第3の出力使用して、私の場合には、多少の問題を回避:

el = 0.25; 
A = (randi([7364 84635],[1e4 1]))/1e3; 
B = A/el; 
C = round(B); 
D = C*el; 
[tmp1,tmp2,tmp3] = unique(D); 
E = tmp1(tmp3,:); 
all(E==D) 
ans = 
    1 

正しくビニングを行います。したがって、中心点は無限精度で正確ではないかもしれませんが、元のデータの3桁の精度よりも少なくとも10桁以内です。