[Java] Generating a Time Array Problem

  • Context: Comp Sci 
  • Thread starter Thread starter testme
  • Start date Start date
  • Tags Tags
    Array Java Time
Click For Summary

Discussion Overview

The discussion revolves around generating a time array in Java, given a maximum time and a time step. Participants explore issues related to floating-point precision, array sizing, and loop conditions in the context of programming and numerical representation.

Discussion Character

  • Homework-related
  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant describes the problem of generating a time array from 0 to a maximum time using a specified time step, providing initial code that encounters floating-point precision issues.
  • Another participant questions the binary representation of 0.05 and suggests using String.format to address formatting issues related to floating-point numbers.
  • Some participants discuss the implications of rounding errors when calculating the array size, particularly when the result of tMax/tStep is not an integer.
  • There is a suggestion to modify the loop condition to avoid exceeding the maximum time by comparing the index directly to the array length instead of using a calculated condition.
  • Participants debate whether Java truncates or rounds when casting from double to int, with references to behavior in other programming languages.
  • One participant proposes an alternative method for populating the array that could mitigate rounding errors by directly calculating the time values based on the index.

Areas of Agreement / Disagreement

Participants express differing views on how to handle floating-point precision and array sizing, with no consensus reached on the best approach to avoid errors. The discussion remains unresolved regarding the optimal solution to the problem presented.

Contextual Notes

Limitations include potential rounding errors inherent in floating-point arithmetic, the assumption that tMax is a multiple of tStep, and the implications of array indexing in relation to loop conditions.

testme
Messages
68
Reaction score
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
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:
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;
 
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.
 
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:
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.
 
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:
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.
 
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:

Similar threads

  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 7 ·
Replies
7
Views
3K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 18 ·
Replies
18
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 7 ·
Replies
7
Views
3K
  • · Replies 12 ·
Replies
12
Views
2K
  • · Replies 5 ·
Replies
5
Views
2K