मुझे वास्तव में बहुत आश्चर्य हुआ कि मैं इसका उत्तर यहाँ नहीं पा रहा था, हालाँकि शायद मैं गलत खोज शब्दों या किसी चीज़ का उपयोग कर रहा हूँ। निकटतम मैं मिल सकता है इस है, लेकिन वे की एक विशिष्ट श्रेणी पैदा करने के बारे में पूछने 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]
क्या कोई मौजूदा लाइब्रेरी है जो पहले से ही इस तरह की कार्यक्षमता प्रदान करती है?
यदि नहीं, तो क्या मेरे दृष्टिकोण से कोई समस्या है?
क्या किसी के पास इसके लिए एक बेहतर दृष्टिकोण है?