จริง ๆ แล้วฉันประหลาดใจมากฉันไม่สามารถหาคำตอบได้ที่นี่ แต่บางทีฉันแค่ใช้คำค้นหาที่ผิดหรืออะไรบางอย่าง ที่ใกล้เคียงที่สุดที่ฉันสามารถหาได้คือสิ่งนี้แต่พวกเขาถามเกี่ยวกับการสร้างช่วงที่เฉพาะเจาะจง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]
มีห้องสมุดที่มีฟังก์ชันการทำงานประเภทนี้อยู่แล้วหรือไม่?
ถ้าไม่มีปัญหากับแนวทางของฉันหรือไม่?
ใครบ้างมีวิธีที่ดีกว่านี้?