[Java] Generating a Time Array Problem

In summary: I made a mistake in my post - should have been (int)(tmax/tstep), not (int)(tmax/tstep) + 1. The array size will be (int)(tmax/tstep) + 1, where (int)(tmax/tstep) will always be an integer, so the array size will always be one larger than needed.
  • #1
testme
68
0

Homework Statement


I'm given a maximum time, a time step (or interval) and I'm supposed to form an array from 0 to the maximum time going up by timestep each time.

double tMax; //maximum time
double tStep; //time interval to go up by

Homework Equations


Our teacher told us to use the following equation:
ti = ti-1 + tStep

The Attempt at a Solution



public static double[] timeArray(double tMax, double tStep)
{
double[] timeArr = new double[(int)(tMax/tStep) + 1];
timeArr[0] = [0];
for(int i = 1; timeArr[i - 1] <= tMax; i++)
{
timeArr = timeArr[i - 1] + tStep;
}
return timeArr;
}

public static void displayTime(double[] timeArr)
{
int n = timeArr.length;
System.out.println("Time");
for(int i = 0; i < n; i++)
{
System.out.println(timeArr);
}
}

Everything seems to be working however when I print out the time array (using 1 as tMax and 0.05 as tStep) it gives me the list of values such as:

0.0
0.05
0.1
0.15000000000000002
0.2
0.25
0.3
0.35
0.39999999999999997
0.44999999999999996
0.49999999999999994
0.5499999999999999
0.6
0.65
0.7000000000000001
0.7500000000000001
0.8000000000000002
0.8500000000000002
0.9000000000000002
0.9500000000000003
1.0000000000000002

Can anyone tell me why it's adding or taking off .000000000000000#? and how to fix it
 
Physics news on Phys.org
  • #2
Can you write 0.05 in binary?

String.format will help with your problem.

On the subject of rounding errors, what will the array size be if tmax/tstep is 11.99999999? What will happen with the populating loop if you use tmax=0.5 and tstep=0.05?
 
Last edited:
  • #3
Ibix said:
Can you write 0.05 in binary?

String.format will help with your problem.

On the subject of rounding errors, what will the array size be if tmax/tstep is 11.99999999? What will happen with the populating loop if you use tmax=0.5 and tstep=0.05?
Umm, do you mean when the user enters it or in general?

if I remember right
1111

Also, I don't think we're allowed to use string format.

I believe we're supposed to assume that tMax = ntStep, where n can be any integer. So tMax/tStep can't be 11.999999999 or anything of the sort.

using tmax = 0.5, tstep = 0.05

(tmax/tstep) + 1 = 11
timeArr = new double[11];

timeArr[0] = 0;
timeArr[1] = 0.05;
timeArr[2] = 0.1;
timeArr[3] = 0.15;
timeArr[4] = 0.2;
timeArr[5] = 0.25;
timeArr[6] = 0.3;
timeArr[7] = 0.35;
timeArr[8] = 0.4;
timeArr[9] = 0.45;
timeArr[10] = 0.5;
 
  • #4
Ibix said:
Can you write 0.05 in binary?

testme said:
if I remember right
1111
No. 1111 is the binary representation of 1510. The binary representation of .05 is an infinitely long binary fraction. Since computers can't hold infinitely long numbers, they truncate them to fit, which causes truncation errors. This is why you are getting the results you show.
 
  • #5
To reduce rounding error related to repeated additions, try changing

Code:
    timeArr[i] = timeArr[i - 1] + tStep;

to

Code:
    timeArr[i] = i * tStep;

It's also possible to reduce rounding errors due to repeated additions by using a function and an array of 2048 doubles to hold intermediate sums where the index into the array is based on the exponent of 2 of a double precision number ( index = (doubletolongbits(...) >>> 52) & 0x7ff; ), but that's way beyond what is needed for this problem, since it's normally used when summing up a huge list of numbers. The array is initialized to zero, and each time a new number is to be added, the index for that number is generated. If array[index] == 0. , then the number is just stored, else number = number + array[index]; , array[index] = 0.; , and the process repeated until array[index] == 0. and the number stored (or until overflow is detected). Once all numbers have been added, then the array is summed from index = 0 to index = 0x3ff to produce the sum. The purpose of this is to only add numbers with the same exponent of 2.
 
Last edited:
  • #6
testme said:
Umm, do you mean when the user enters it or in general?

if I remember right
1111
I don't think I can add to Mark44's post.

testme said:
Also, I don't think we're allowed to use string format.
Then you'll have to think about how to round a number off (I don't recall whether or not Java does this natively - check Math, or Google for a solution).

testme said:
I believe we're supposed to assume that tMax = ntStep, where n can be any integer. So tMax/tStep can't be 11.999999999 or anything of the sort.
...unless there's a rounding error. The wise programmer always assumes that floats and doubles are a little bit off the mark.

testme said:
using tmax = 0.5, tstep = 0.05

(tmax/tstep) + 1 = 11
timeArr = new double[11];

timeArr[0] = 0;
timeArr[1] = 0.05;
timeArr[2] = 0.1;
timeArr[3] = 0.15;
timeArr[4] = 0.2;
timeArr[5] = 0.25;
timeArr[6] = 0.3;
timeArr[7] = 0.35;
timeArr[8] = 0.4;
timeArr[9] = 0.45;
timeArr[10] = 0.5;
That's not what the results in your first post say. They have a rounding error such that timeArr[10]<0.5, which should cause an exception at the end of the populating loop.
 
  • #7
Ibix said:
what will the array size be if tmax/tstep is 11.99999999?
Based on testme's code, and allowing (int) to always round down (I assume that normally it just rounds to nearest integer):

array size = (int)(tmax/tstep) + 1 = 11 + 1 = 12.

If (tmax/tstep) is an exact integer, then the array size will be one larger than needed.
 
Last edited:
  • #8
rcgldr said:
Based on testme's code, and allowing (int) to always round down (I assume that normally it just rounds to nearest integer):

array size = (int)(tmax/tstep) + 1 = 11 + 1 = 12.

If (tmax/tstep) is an exact integer, then the array size will be one larger than needed.
No - taking the tmax/tstep=10 example from testme's last post, you need 11 array elements (0, 1, ... 10). If tmax/tstep were 9.999, he'd be short an element.
 
  • #9
Ibix said:
Taking the tmax/tstep=10 example from testme's last post, you need 11 array elements (0, 1, ... 10). If tmax/tstep were 9.999, he'd be short an element.
Good catch. I missed the part about the first step starting at zero. Also I wasn't sure if Java (int) typecast truncates or rounds. C (int) typecast truncates. If it truncates like C, then it should be (int) ( (tmax/tstep) + 0.5) + 2 , since the for statement for(int i = 1; timeArr[i - 1] <= tMax; i++) could allow going a partial step beyond tmax. For example, if tmax = 10. and tstep = 3., then the for loop iterates i from 1 to 4, requiring the array size to be 5.

testme hasn't replied to this thread lately, so I don't know if he/she is still looking at this.
 
  • #10
Thanks for all the replies but I figured out a secondary way that checks when the loop should stop which makes it work

instead of comparing when the last element in the array is tMax I compared when i < ((int)(tMax/tStep + 1))
 
  • #11
I'd just use i<timeArr.length, if I were you. A good rule of thumb is never to calculate something twice. One, you save time (not a lot, in this case); two, if you need to change something you don't have to search through your code for it; three, someone coming to your code cold can instantly see that you're populating the whole array without having to do any calculation.

rcgldr: yeah, Java just truncates. I'm not aware of a language that rounds in a cast, but I haven't done a proper survey. :smile:
 
  • #12
Ibix said:
rcgldr: yeah, Java just truncates. I'm not aware of a language that rounds in a cast.
I don't know Java or the other new languages (except for C / C++). For older languages like Pascal, cast is not a type conversion, just a re-interpetation of the bits without modification of those bits (no conversion) casting a float of 1.0 to integer makes it an integer = 0x3f800000. In C / C++, you can do this by casting via a pointer: * (int *) (&float_variable). Fortran has multiple float or double to integer type conversion functions, some that truncate, others that round.

Using timeArr.length as you mentioned would solve the problem. With C / C++, you could use (sizeof(timeArr) / sizeof(double)) to get the "length".
 
Last edited:

1. How can I generate a time array in Java?

To generate a time array in Java, you can use the LocalTime class from the java.time package. This class represents a time value without a date and can be easily manipulated and formatted.

2. What is the format of a time array in Java?

In Java, a time array is typically stored as an array of LocalTime objects. Each LocalTime object represents a specific time value, such as 10:30 AM.

3. How can I customize the time array generated in Java?

You can customize the time array generated in Java by using the LocalTime class's methods, such as of() to specify a specific time, plusHours() to add or subtract hours, and format() to specify a specific time format.

4. Can I generate a time array with both hours and minutes in Java?

Yes, you can generate a time array with both hours and minutes in Java by using the of() method from the LocalTime class. For example, LocalTime.of(10, 30) will create a time value of 10:30 AM.

5. How can I convert a time array to a different time zone in Java?

To convert a time array to a different time zone in Java, you can use the withZone() method from the ZonedDateTime class. This method allows you to specify a different time zone to convert the time array to.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
2
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
18
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
7
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
7
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
4
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
12
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
5
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
21
Views
2K
Back
Top