0

我试图在java中将一个数字数组四舍五入到小数点后三位,原因是我遇到了OutOfMemoryError(数组超出了VM的限制)。我很好奇是否有一种方法可以做到这一点,而无需编写全新的方法或类似的任何激烈的东西。

编辑:这是所有代码

public class GuitarHero {
public static void main(String[] args) {


    int index = 0;
    double sample = 0.0;
    String keyboard ="1234567890qwertyuiopasdfghjklzxcvbnm,";

    GuitarString[] string = new GuitarString[keyboard.length()];

    for(int i = 0; i < 37; i++) {
        double concert = 110.0 * Math.pow(2,i-24);
        string[i] = new GuitarString(concert);
    }

    while (true){

        if (StdDraw.hasNextKeyTyped()) {
            char key = StdDraw.nextKeyTyped();
            index = keyboard.indexOf(key);

            if (index >= 0 && index < 37){
                string[index].pluck();
            }
            //sample = string[index].sample() + string[index+1].sample();
            //StdAudio.play(sample);
        }

        for(int i=0; i<37; i++){
            sample = string[i].sample();

            StdAudio.play(sample);
        }

            for(int i = 0; i < 37; i++){
                    string[i].tic();
            }           
        }   

    }
}

代码1结束

public class GuitarString {

    private RingBuffer buffer; // ring buffer
    // YOUR OTHER INSTANCE VARIABLES HERE
    private int ticTimes = 0;
    // create a guitar string of the given frequency
    public GuitarString(double frequency) {
        // YOUR CODE HERE
    int N;
    N = (int)(44100/frequency);
    buffer = new RingBuffer(N);
    for (int i=1; i <=N; i++ ){
       buffer.enqueue(0.0);        
        }
    }

    // create a guitar string whose size and initial values are given by the array
    public GuitarString(double[] init) {
        // YOUR CODE HERE
    buffer = new RingBuffer(init.length);
    for (int i = 0; i < init.length; i++){
        buffer.enqueue(init[i]);
        }
    }

    // pluck the guitar string by setting the buffer to white noise
    public void pluck() {
        // YOUR CODE HERE
        while(!buffer.isEmpty()) buffer.dequeue();
    while(!buffer.isFull()){
    buffer.enqueue(Math.random()-0.5);
}
}

    // advance the simulation one time step
    public void tic() {
        // YOUR CODE HERE
    double value1, value2;
    value1 = buffer.dequeue();
    value2 = buffer.peek();
        buffer.enqueue(((value1+value2)/2)*0.996);
    ticTimes++;
    }

    // return the current sample
    public double sample() {
        // YOUR CODE HERE
    return buffer.peek();
    }

    // return number of times tic was called
    public int time() {
        // YOUR CODE HERE

    return ticTimes;
    }


  public static void main(String[] args) {
      int N = Integer.parseInt(args[0]);
      double[] samples = { .2, .4, .5, .3, -.2, .4, .3, .0, -.1, -.3 };  
      GuitarString testString = new GuitarString(samples);
      for (int i = 0; i < N; i++) {
          int t = testString.time();
          double sample = testString.sample();
          System.out.printf("%6d %8.4f\n", t, sample);
          testString.tic();
      }
  }

}

代码2结束

public class RingBuffer {
private int first;            // index of first item in buffer
private int last;             // index of last item in buffer
private int size;             // current number of items of buffer
private double[] buffer;

// create an empty buffer, with given max capacity
public RingBuffer(int capacity) {
    // YOUR CODE HERE
    buffer = new double[capacity];
    first =0;
    last  =capacity-1;
    size  =0;
}

// return number of items currently in the buffer
public int size() {
    // YOUR CODE HERE
    return size;
}

// is the buffer empty (size equals zero)?
public boolean isEmpty() {
    // YOUR CODE HERE
    if (size == 0) 
    return true;
    else 
    return false;
}

// is the buffer full (size equals array capacity)?
public boolean isFull() {
    // YOUR CODE HERE
    if (size == buffer.length)
    return true;  
    else
    return false;

}

// add item x to the end
public void enqueue(double x) {
    if (isFull()) { throw new RuntimeException("Ring buffer overflow"); }
    // YOUR CODE HERE
    last = (last+1)%buffer.length;
    buffer[last]=x;
    size++;
}

// delete and return item from the front
public double dequeue() {
    if (isEmpty()) { throw new RuntimeException("Ring buffer underflow"); }
    // YOUR CODE HERE
    double temp = buffer[first];
    first = (first+1)% buffer.length;
    size--;
    return temp;
}

// return (but do not delete) item from the front
public double peek() {
    if (isEmpty()) { throw new RuntimeException("Ring buffer underflow"); }
    // YOUR CODE HERE
    return buffer[first];
}

// a simple test of the constructor and methods in RingBuffer
public static void main(String[] args) {
    int N = Integer.parseInt(args[0]);
    RingBuffer buffer = new RingBuffer(N);
    for (int i = 1; i <= N; i++) {
    buffer.enqueue(i);
    }
    double t = buffer.dequeue();
    buffer.enqueue(t);
    System.out.println("Size after wrap-around is " + buffer.size);
    while (buffer.size() >= 2) {
    double x = buffer.dequeue();
    double y = buffer.dequeue();
    buffer.enqueue(x + y);
    }
    System.out.println(buffer.peek());
}

}

谢谢!

4

1 回答 1

2

那么在该循环的第一次迭代中,代码试图分配一个包含 1,681,534,603 个双精度数 (44100 / (110 * 2^-22)) 的数组,这将需要大约 3GB 的内存。我建议你找到一个不同的解决方案。

于 2012-11-28T16:07:08.397 回答