I have this class that works on pixels of a sequence of images
private int makeRSR(int x, int y)
{
double bRed = 0;double bGreen = 0; double bBlue = 0;
for(int k: sequence.keySet())
{
BufferedImage img = sequence.get(k);
for(int i=0; i<iteration; i++){
for(int j=0;j<spray_int; j++){
int dist= ((int)(dis_int*Math.random()));
double theta=((int)(361*Math.random())) ;
double inc_x=dist * Math.cos((theta*(Math.PI/180)));
double inc_y=dist * Math.sin((theta*(Math.PI/180)));
int row=Math.abs((int)(inc_y+y));
int column=Math.abs((int)(inc_x+x));
if(row<1 || column<1 || row>altI-1 || column>largI-1){
row=Math.abs((int) ((altI-1)*Math.random()));
column=Math.abs((int) ((largI-1)*Math.random()));
}
Color c = new Color(img.getRGB(column,row));
red.add(c.getRed());
green.add(c.getGreen());
blue.add(c.getBlue());
}
Color c = new Color(img.getRGB(x,y));
red.add(c.getRed());
green.add(c.getGreen());
blue.add(c.getBlue());
double maxR=max(red);
double maxG=max(green);
double maxB=max(blue);
bRed += ((((double)c.getRed()) / (maxR))*255.00);
bGreen += ((((double)c.getGreen()) / (maxG))*255.00);
bBlue += ((((double)c.getBlue()) / (maxB))*255.00);
red.clear();green.clear();blue.clear();
}
}
redValue=0;greenValue=0;blueValue=0;
redValue= (int) (bRed/(iteration*(sequence.size())));
greenValue= (int) (bGreen/(iteration*(sequence.size())));
blueValue=(int) (bBlue/(iteration*(sequence.size())));
bRed=0.0;bGreen=0.0;bBlue=0.0;
return new Color(redValue,greenValue,blueValue).getRGB();
}
the problem is that sometimes c.getRed() and maxR are both 0 (same for the other channels) and so bRed loses its content and take value NaN, and it never change. Is there an error, something I missed, or do I have to prevent the 0/0 by adding a check?
Thanks, Bye
Since 0/0 is an undefined number you need to decide how do you want do treat it.
Find out why you get both 0 in current and max red values and prevent it.
Set result of division to 0 (or any number you decide to get the expected result) if both c.getRed() and maxR are 0.
Because dividing by zero is an error, it results in NaN, which stands for Not a Number. Subsequent operations involving NaN will also result in NaN, that's why it's value never changes afterwards.
You should explicitly check for zero divident before division to prevent division by zero.
Related
For this formula:
I had to make a method to automate it, and I've received 4 examples to try it out.
x = 1 > p = 2
x = 3 > p = -226
x = 4 > p = 9854
however, when I insert 11 the answer should be 3.0198773447 and I receive -1.78316945E8 instead :/
here is my code:
System.out.println("Insira o numero: ");
int x = input.nextInt();
int fat = 1;
int contador = 0;
int contador1 = 0;
double p = 0;
for(double i = 1; i <=x; i++){
fat = 1;
contador++;
contador1 = contador* 2;
for(double j = 1; j <= contador1; j++){
fat *=j;
}
if(contador <=1){
p += fat / contador;
}
if(contador % 2 ==0 && contador > 1){
p += fat / contador;
}else if( contador % 2 != 0 && contador > 1){
p -= fat / contador;
}
}
System.out.println(p);
If you type in 11, that means contador1 will become as high as 22 (you will loop 11 times, every loop you first increment contador, and contador1 is twice that, so, 22. In other words, you'll end up having to calculate 22!.
The int type does not hold any arbitrary integer. It can only hold integers between -2^31 and +2^31-1. If you try to go beyond those bounds, it just loops around. Witness it in action:
int x = Integer.MAX_VALUE; // a constant representing 2^31-1.
int y = x + 1;
System.out.println(x);
System.out.println(y);
// Prints: 2147483647
// -2147483648
Where'd that minus come from? That's that whole 'loops around' thing. 22! is much lager than than this upper bound. Hence, your code doesn't work and it also explains why your algorithm tosses a negative number in there.
You could choose to use long instead which can hold it, but long, too, has limits - 2^63-1 to be precise. You could use double which goes ever further (up to about 1e308 which is a lot more than 2^63), but doubles are not accurate and the lack of accuracy gets worse as you move further away from 0. Past 2^53 or so, the distance between 2 representable numbers in the double range is more than 1, meaning, +1 no longer does anything (all operations on double values are rounded to the nearest representable double after every operation).
More generally trying to do 'math' on really large numbers is a non-trivial affair, and your basic + and / can no longer get the job done. Look up the API of BigDecimal which guarantees you perfect accuracy at the cost of, naturally, performance. You could use that, and get perfect answers. Though it'll take a while.
I want to print 0.5000 value in java therefor I try BigDecimal for this purpose but when i divide i get 0.5 with red color.
Can i print 0.5000 using BigDecimal if not then why and why does 0.5 print in red font?
My code is:
static void plusMinus(int[] arr) {
Double n = 0.0, p = 0.0, z = 0.0;
for(int i = 0; i < arr.length; i++) {
if(arr[i] < 0) n++;
else if(arr[i] > 0) p++;
else z++;
}
n = BigDecimal.valueOf(n/arr.length).setScale(4,RoundingMode.HALF_UP).doubleValue();
p = BigDecimal.valueOf(p/arr.length).setScale(4,RoundingMode.HALF_UP).doubleValue();
z = BigDecimal.valueOf(z/arr.length).setScale(4,RoundingMode.HALF_UP).doubleValue();
System.err.println(p); // print:0.5 //(in red font)
System.out.println(n); // print:0.3333
System.out.println(z); // print:0.1667
}
n = BigDecimal.valueOf(n/arr.length).setScale(4,RoundingMode.HALF_UP).doubleValue();
The result of the right hand side is a double: and it gets autoboxed to a Double to assign it to the left hand side. When you print n, you're not printing a BigDecimal, but rather a Double.
There is no such thing as a Double (or a double) 0.5000 as distinct from a Double (or a double) 0.5. 0.5000 == 0.5: they are the same value.
Since there is no scale information stored in a Double (or a double), there is no way of knowing that you want 0.5000 as opposed to 0.5 or 0.500000000.....000.
If you want to print with a certain number of decimal places, either use a NumberFormatter of some flavour, or keep it as a BigDecimal.
I want to convert a double value to int when and only when 2 numbers after the dot are 0.
Example
double x = 25.001
You can use this :
double x = 25.001;
int i = (int) x;
System.out.println(x);//Input
if (x - i <= 0.01) {
x = (int) x;
}
System.out.println(x);//Output
RESULT
Input Output
25.001 25.0
25.011 25.011
If you want to use a second variable you can use :
int y = 0;
if (x - i <= 0.01) {
y = (int) x;
}
Note
But note, in case your input is not correct, you will always get 0, i like the first solution it is good then the second.
if(x-Integer.parseInt(x)>=0.001)
//Convert here
That rounded number you then cannot store in a double, as a double is always an approximation of a real value - of a series of a (negative) power of 2.
So you should go for BigDecimal as many do that want to do financial software.
If you did something like:
double adjustWhenCloseToInt(double x) {
long n = Math.round(x); // Could overflow for large doubles
if (Math.abs(x - n) < 0.01) {
x = n;
}
return x;
}
A simple
x = adjustWhenCloseToInt(x);
System.out.print(x);
Could still print 0.00000001 or such.
The solution there is
System.out.printf("%.2f", x);
Or better use a localized MessageFormat (thousand separators and such).
As floating point always bears rounding errors, I would in general go for BigDecimal, though it is a circumstantial class to use. Take care to use String constructors:
new BigDecimal("3.99");
As they then can maintain a precision of 2.
For some reason whenever I try to run this code, speed remains at 0 and it counts i up to x and then speed is suddenly changed to 1.0. speed is supposed to be a decimal of x depending on how many times the for-loop has run through. I don't understand why this is happening and would be very grateful for some clarity.
double speed;
int x = 200;
for(int i = 0; i <= x; i++){
speed = i/x;
System.out.println("Speed- " + speed);
System.out.println("Ticks- " + i);
}
for(int i = x; i >= 0; i--){
speed = i/x;
System.out.println("Speed- " + speed);
System.out.println("Ticks- " + i);
}
Try this:
double x = 200; // use a double instead of an int
The problem? you were dividing two ints, and the result is another int. By converting one of the two operands to a double, the division will now yield a number with decimals.
x must be an float variable in order to get the correct result. If both, i and x are integers, speed is an integer too, and that's the reason you get only 0 and 1
For some reason my math just returns 0. The value are set, I have checked.
int currentSize = 4079;
int totalSize = 500802;
int percentage = ((currentSize/totalSize) * 100);
progdialog.setProgress(percentage);
Percentage always equals percentage.
Why?
The problem, as other have pointed out, is integer division will turn anything less than 1 to zero. This happens before multiplying by 100. You can change the order of operations to get something better:
int percentage = currentSize * 100 / totalSize;
If you are concerned about rounding, you can use
int percentage = (currentSize * 100 + (totalSize >> 1)) / totalSize;
These avoid the expense of working with double or float values.
you are using 'int's for currentSize and totalSize which results in integer division which removes the fractional part, yielding 0. hence the percentage is always 0.
change it to float percentage = (((float)currentSize/totalSize) * 100); and things will be fine
I assume currentSize and totalSize are int.
currentSize = 4079;
totalSize = 500802;
If they are, then currentSize/totalSize is an integer division. The result will have no fractional part (the fractional part is removed, no round up). Therefore the result is 0.
If one of the operand is double, the result of division will have fraction. Therefore, I cast one integer operand to double.
(double) currentSize
After the calculation, if you want the result to store in int, you have to cast (convert double to int; remove fractional part).
int percentage = (int) ((double) currentSize ...
The whole code is:
int currentSize = 3;
int totalSize = 100;
int percentage = (int) ((double) currentSize / totalSize * 100);
System.out.println(percentage);
If currentSize and totalSize are integers, this calculation will do integer division, which will truncate your fraction down to 0. Use doubles.
Change your code to this:
double percentage = ((double)(currentSize/totalSize) * 100);
progdialog.setProgress(percentage);
Hope it will help yout. :)
Because the result of your calculation is a double with value less than 1. You put it in an integer so it truncates everything behind the decimal separator, resulting in zero. Try storing the value in a double instead.
double occupancyRate = 0.0;
int occupiedRoomsTotal = 12;
int totalRooms = 20;
occupancyRate = (((double) occupiedRoomsTotal / totalRooms)) * 100;
DecimalFormat df2 = new DecimalFormat("#.##");
System.out.println("Occupancy Rate = " + df2.format(occupancyRate) + "%");
Java Division of integers yields zero if both numerator and denominator are both integers and the result is less than 1.
Fix:
Make either of the operands to be floating number or double
e.g. int x = 1;
double y = 3.0;
x/y gives 0.333333
where as 1/3 results in 0.