ここでこれに対する答えを見つけることができなかったのは、実際には非常に驚いていますが、おそらく間違った検索用語などを使用しているだけです。私が見つけることができる最も近いのはこれですがdouble
、特定のステップサイズで特定の範囲のを生成することについて質問され、答えはそれをそのように扱います。任意の開始、終了、ステップサイズで数値を生成するものが必要です。
私はそこに理解があるどこかにすでにライブラリーでは、このようないくつかの方法であると、私は簡単にそれを見つけることができませんでしたので、あれば(再び、多分私はちょうど間違った検索語か何かを使用しています)。これが、これを行うために私が最後の数分間で自分で調理したものです。
import java.lang.Math;
import java.util.List;
import java.util.ArrayList;
public class DoubleSequenceGenerator {
/**
* Generates a List of Double values beginning with `start` and ending with
* the last step from `start` which includes the provided `end` value.
**/
public static List<Double> generateSequence(double start, double end, double step) {
Double numValues = (end-start)/step + 1.0;
List<Double> sequence = new ArrayList<Double>(numValues.intValue());
sequence.add(start);
for (int i=1; i < numValues; i++) {
sequence.add(start + step*i);
}
return sequence;
}
/**
* Generates a List of Double values beginning with `start` and ending with
* the last step from `start` which includes the provided `end` value.
*
* Each number in the sequence is rounded to the precision of the `step`
* value. For instance, if step=0.025, values will round to the nearest
* thousandth value (0.001).
**/
public static List<Double> generateSequenceRounded(double start, double end, double step) {
if (step != Math.floor(step)) {
Double numValues = (end-start)/step + 1.0;
List<Double> sequence = new ArrayList<Double>(numValues.intValue());
double fraction = step - Math.floor(step);
double mult = 10;
while (mult*fraction < 1.0) {
mult *= 10;
}
sequence.add(start);
for (int i=1; i < numValues; i++) {
sequence.add(Math.round(mult*(start + step*i))/mult);
}
return sequence;
}
return generateSequence(start, end, step);
}
}
これらのメソッドstep
は、シーケンスインデックスを乗算してstart
オフセットに追加する単純なループを実行します。これにより、連続的なインクリメントで発生する浮動小数点エラーの複合(step
各反復でを変数に追加するなど)が軽減されます。
generateSequenceRounded
小数ステップサイズが顕著な浮動小数点エラーを引き起こす可能性がある場合のためにメソッドを追加しました。これはもう少し算術を必要とするので、私たちのような非常にパフォーマンスに敏感な状況では、丸めが不要なときに単純な方法を使用するオプションがあると便利です。ほとんどの一般的な使用例では、丸めのオーバーヘッドは無視できると思います。
私は意図的のような「異常」の引数を処理するためのロジックを除外することを注意Infinity
、NaN
、start
> end
、負またはstep
簡略化のためにサイズとは、手元の問題に焦点を当てることを望みます。
次に、使用例と対応する出力の一部を示します。
System.out.println(DoubleSequenceGenerator.generateSequence(0.0, 2.0, 0.2))
System.out.println(DoubleSequenceGenerator.generateSequenceRounded(0.0, 2.0, 0.2));
System.out.println(DoubleSequenceGenerator.generateSequence(0.0, 102.0, 10.2));
System.out.println(DoubleSequenceGenerator.generateSequenceRounded(0.0, 102.0, 10.2));
[0.0, 0.2, 0.4, 0.6000000000000001, 0.8, 1.0, 1.2000000000000002, 1.4000000000000001, 1.6, 1.8, 2.0]
[0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0]
[0.0, 10.2, 20.4, 30.599999999999998, 40.8, 51.0, 61.199999999999996, 71.39999999999999, 81.6, 91.8, 102.0]
[0.0, 10.2, 20.4, 30.6, 40.8, 51.0, 61.2, 71.4, 81.6, 91.8, 102.0]
この種の機能を提供する既存のライブラリはすでにありますか?
そうでない場合、私のアプローチに問題はありますか?
誰かこれにもっと良いアプローチがありますか?