Why is my float automatically rounding and how do i get it to stop
I don't want to use double if I don't have to because I want to save memory. Here is the code using double:
Code Java:
short mag;
int magx;
short y=154;
short x=612;
double yx=0.0;
for(mag=1;mag<=1000;mag*=10){
if(mag>x){
magx=mag*mag+x;
System.out.println(magx);
yx=(double)(magx)/(mag*mag*10)+y;
break;
}
}
System.out.println("mag: "+mag+", and yx: "+yx+", and y: "+y+", and x: "+x);
The output of magx looks like this :1000612
The (correct) output of yx looks like this: 154.1000612 (using double)
But when I use float, it looks like this: 154.10007
To clear up what the number needs to be:
-the y value before the decimal point
-the mag value immediately after the decimal point
-the x value after the mag
Re: Why is my float automatically rounding and how do i get it to stop
Quote:
I want to save memory
How much memory are you worried about?
How many decimal places can a float hold? Is it enough for your app?
Re: Why is my float automatically rounding and how do i get it to stop
Well this program is going to be gigantic so I'm trying to use the smallest data types possible at every opportunity.
Re: Why is my float automatically rounding and how do i get it to stop
You need to decide where to compromise: precision vs memory. I'd say that these days memory isn't a typical issue unless you are dealing with huge volumes of data...you can increase heap size by setting the -Xmx or -Xms command line parameters if you receive out of memory exception. If you are dealing with huge volumes of data, you can many times compromise between saving and reading into memory. When you say gigantic, what scale are you talking about?
Re: Why is my float automatically rounding and how do i get it to stop
well I'm not super experienced, but the I have already seen the out of memory exception so far. I forget where, it may have been a mess up with a while loop. In terms of a rough estimation of the potential size of the current part of my program, it includes:
y=int (maybe upwards of a million)
x=int (maybe upwards of a million)
and then for all of y and x:
-around 6 2 dimensional boolean arrays
-around 5 2 dimensional byte arrays
-around 6 lists (4 short, 2 byte, maybe more)
and over 10 for loops so far, most of them double for loops.
And I'm planning on adding a 3rd dimension soon. I know it seems unneccessarily large, but I haven't gotten around to seeing where I can combine certain parts of code yet to reduce for loops. Right now I'm just making sure it works, and using the smallest variables possible (like if i know i won't use a number bigger than 60 i use byte).
So I have to use double to get the result I want? It's not that big of a deal here, but it may be in different places.
Re: Why is my float automatically rounding and how do i get it to stop
Quote:
y=int (maybe upwards of a million)
Do you mean an array holding a million int? For example:
int[] bigArray = new int[1000000000];
Re: Why is my float automatically rounding and how do i get it to stop
Just because you're using doubles in loops doesn't mean you have to keep track of all the doubles used, just the ones for that iterations.
So for example:
Code Java:
for(int i = 0; i < 100; ++i)
{
double a = Math.random();
a += i;
}
This will roughly only require heap memory space for an int (i) and a double (a), not 100 int's and 100 double's.
What is it you're trying to do? There may be a more efficient method to do what it is you want.
Floats vs. doubles is always a trade off between precision vs. size (there is a small speed factor, but it is essentially negligible in all cases except for data transfer).
As a rule of thumb:
floats give you ~7-8 decimals of precision and doubles give you ~15-16 decimals of precision. This applies with each math operation, not at the end of a statement so you error will stack and can grow very quickly if you're not careful.
Re: Why is my float automatically rounding and how do i get it to stop
Well I need the precision more so I'll have to use doubles for this. The y and x are not a million right now, I've been working with around 200x100 max just to weed out errors. But it can be expanded to that by changing the variables after. The reason I need the doubles in this way is because, I need to make a list that holds the y and x value rather than using two lists because if I use two lists then at one point I say:
if (!xlist.contains(n)&&!ylist.contains(n)). The problem here is I'm discounting one pair but the list will contain multiples of the same variables like:
xlist(0)=1, ylist(0)=4
xlist(1)=1, ylist(1)=3
And so I'm not sure (I haven't ran the code because I would have to make a pretty big separate example just to see if I'm right) but I'm pretty sure it will always be false as long as each list contains the variable i'm looking for. By making a double that holds the y, the mag, and the x, I can check both at the same time by separating the y and using the mag to get the x. I have thought of a multidimensional arraylist but I don't think it will work for this.
Re: Why is my float automatically rounding and how do i get it to stop
Quote:
By making a double that holds the y, the mag, and the x, I can check both at the same time by separating the y and using the mag to get the x.
Can you explain the program requirement for all that? What is it you are trying to do?
It looks like you are trying to store 3 data values in one variable of type double.
What are the ranges in values for each of these values?
Re: Why is my float automatically rounding and how do i get it to stop
the range is also a potential problem, it seems using double, I cannot exceed an x value beyond 99999, if I'm using my current method. But that's probably okay, because I can see other ways around that.
And yes, I'm trying to store 3 variables in 1, it works for my needs, it's just limited at the above (but not for y, or for x if I switch the placement of each around for x.magy). The max for y is between 333333 and 222222, but then the max for x is 99998. I could figure that out by looking at the size of the variables I'm using, which by the way I've changed to longs and ints just to see the max I could use.
What I was doing before:
-add an x and a y to separate lists when a condition is met. The x and y already exist and there are multiples of each (0,0),(0,1),(1,0),(1,1) etc. So when I get a pair later in a different condition, I ask if each list does not contain that variable. Say I want to see if (0,1) exists, I would ask x if it had 0 and y if it had 1. But not only would it say (0,1) makes it true, but so does other examples, because this is not an array, but two separate lists. It just finds the first occuring object that meets the condition. But by combining both variables into 1 ( (0,1) would be 0.101))I can act like I'm using a 2 dimensional array when i'm using one list but with the limitations I've stated above.
Re: Why is my float automatically rounding and how do i get it to stop
And here is the undo portion of my code:
Code :
System.out.println("mag: "+mag+", and yx: "+yx+", and y: "+y+", and x: "+x);
String breaknum=Double.toString(yx);
short newy;
short newx;
short getmag;
double undox;
for(byte i=0;i<breaknum.length();i++){
if(breaknum.charAt(i)=='.'){
newy=Short.parseShort(breaknum.substring(0,i));
System.out.println("newy: "+newy);
if(breaknum.length()-1<i+2){
newx=0;
System.out.println("newx: "+newx);
}
else{
getmag=(short)(i+2);
while(breaknum.charAt(getmag)=='0')getmag++;
getmag=Short.parseShort(breaknum.substring(i+1,getmag));
System.out.println("getmag: "+getmag);
undox=(yx-0.1-newy)*getmag*getmag*10;
newx=(short)undox;
System.out.println("undox: "+undox+"\nnewx: "+newx);
}
}
}
It works fine, I think I may label this as solved because I don't think it's possible to use float, especially if even double is giving me problems at around 100000. But in the case that y and x both don't exceed 9999, are any of you sure I cannot use float? Like I thought there was someway to extend the decimal place?
Re: Why is my float automatically rounding and how do i get it to stop
If 333333 is the max for one value and 100000 for the other, you could pack them into a long (8 bytes) with no loss of precision.
Your data appears to require 5 bytes to hold the two values.
Pack with OR and Shift. Unpack with AND and Shift
If space savings is more important than processing time, use a 3 char String to pack your data into. 3 char @2 bytes each should hold it.
Quote:
are any of you sure I cannot use float?
For what?
Re: Why is my float automatically rounding and how do i get it to stop
Depends on what your needs are (float for memory efficiency, doubles for precision). I'm still not quite sure what your code is suppose to be doing. What is the higher-level problem you're trying to solve?
If you want "exact" precision (integer values only), use a long and pack/unpack it with bitwise operators. Bitwise operators are considerably faster than math operators, particularly when involving floating point operations.
Re: Why is my float automatically rounding and how do i get it to stop
I'm not sure what you mean by using a long instead but I redid the code using a long instead of a double. I know that double and long also both require 8bytes so I'm not sure if this is more efficient:
Code :
byte xsize=0;
short y=12345;
short x=32123;
int mag;
long yx=0l;
for(mag=1;mag<=1000000;mag*=10){
if(mag>x){
yx=(((long)(mag*y)+x)*10+xsize);
System.out.println(xsize);
System.out.println(yx);
break;
}
xsize++;
}
String breaknum=Long.toString(yx);
xsize=(byte)breaknum.charAt(breaknum.length()-1);
System.out.println("breaknum: "+breaknum+", xsize: "+xsize);
The output is 12345321235, or the y then x then magnitude of x (12345 32123 5). There is one big problem though and I can't figure it out: the new xsize when undoing the breaknum (xsize=(byte)breaknum...) outputs 53 instead of just 5. even if I make it a char first (the char is 5), but then convert that char to byte for xsize (xsize=(byte)(xsizechar)) it still turns xsize into '53'. I think it's giving the char value of 5 but I want to convert the char value literally to 5. If I turn it into a string and then parse it will that work, or is there an easier way to skip that step?
Re: Why is my float automatically rounding and how do i get it to stop
Its hard to offer advice if we don't know What you are trying to do?
You're coding a lot without explaining the objective.
As helloworld922 said:
Quote:
What is the higher-level problem you're trying to solve?
Are you trying to pack two numbers with 500K ranges into a single number for ease of comparing for matching pairs and storage?
Can you explain?
Re: Why is my float automatically rounding and how do i get it to stop
The objective is kind of difficult to explain properly to someone who hasn't seen all of the code but that's not really important. I was originally seeing if it would be possible to use float instead of double and if it would be just as precise. But now, I've swtiched to long, so I have the option of using int or even short on condition that both x and y fit into the value if i want to and have the desired result.
However the new problem is that I need to convert a char to a byte but the byte it returns is the value of the char rather than the char I need. so instead of char x='5' turning into byte xsize=5, i get byte xsize=53.
Re: Why is my float automatically rounding and how do i get it to stop
Quote:
need to convert a char to a byte
You can't. A char has 2 bytes with 64K possible values. A byte has 256 values.
Quote:
use float instead of double and if it would be just as precise
No, a double will be more precise. It depends on how many significant digits you need.
Quote:
have the option of using int or even short on condition that both x and y fit into the value
Why do they both need to fit?
Quote:
char x='5' turning into byte xsize=5, i get byte xsize=53.
Look at the ASCII character table. The char '5' has a decimal value of 53.
To convert a decimal digit character to an int with the digit's value, either subtract '0' from it or use a method from the Character class.
Why do you need to do this?
Re: Why is my float automatically rounding and how do i get it to stop
K, well since you've settled the precision loss problem for float, I'm going to use long for sure now. The reason both x and y have to fit into it is so I can use the smallest data type possible. for example if x=12 and y=23 then I could use short because the value would be under 30something thousand (23122). Same scenario with int. And the largest y and x values I could have, using long would be around 920000000 and 999999999. As for the char value, I just made a string to hold xs then parsed it into byte. Too bad i couldn't just directly convert the char to byte. I need to do this as part of a method for adjusting the variables in my arrays. Thanks for the help
Re: Why is my float automatically rounding and how do i get it to stop
Quote:
if x=12 and y=23 then I could use short
Those values would each fit in a byte, why use a short?
Quote:
a method for adjusting the variables in my arrays.
This is the part we've been asking about. What are the "adjustment"s you are talking about?
Quote:
And the largest y and x values I could have, using long would be around 920000000 and 999999999.
Half of a long can hold 4B, vs the 900M you show