Java - Help converting inches to cm, and weight to kg [closed] - java

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I'm doing a Java exercise, and I need to display a persons height in both inches and cm, as well as their weight in both pounds and kg.. Here's what I came up with, but I'm getting tons of errors.
Height = 74; // inches
Weight = 180; // pounds
System.out.println( "He's " + Height + " inches or + (Height * 2.54) cm tall "." );
I got the 2.54 by just googling what the conversion was for inches to cm. I basically did the same thing for the weight (see below)
System.out.println( "He's " + Weight + " pounds or + (Weight * 2.20) kg heavy "." );
My goal is to get it to display:
He's 74 inches (or 187.96 cm) tall.
He's 180 pounds (or 81.6466266 kg) heavy.
Any help would be great, and sorry for such a basic question!

There are a couple of glaring syntax errors here:
System.out.println( "He's " + Height + " inches or + (Height * 2.54) cm tall "." );
Notice how the syntax highlighting on this page points them out. (Your IDE really should be doing that too.) You close a string at the end, then have a random . character and open another string which you never close.
You can fix the syntax errors by removing a quote:
System.out.println( "He's " + Height + " inches or + (Height * 2.54) cm tall ." );
However, this doesn't yet give you the output you want. Because this is just a string:
" inches or + (Height * 2.54) cm tall ."
Java isn't going to perform that calculation, as far as Java is concerned this is just text. You need to separate the string just like you already are for your other use of the variable:
System.out.println( "He's " + Height + " inches or " + (Height * 2.54) + " cm tall." );

System.out.println( "He's " + Height + " inches or ("+ (Height * 2.54)+" ) cm tall." );
Remember that you must do the conversion (without Strings quotes) before concatenate with text. The final dot is not needed.

First off, you need to define what datatype your variables are. You can't have "Height", you need to have "int Height".
It's also easier if you set variables for both height and weight in their respective units. So you should have a variable for height in inches, and then a variable for height in centimeters.
Here's my solution:
public static void main(String[] args) {
int inHeight = 74;
double cmHeight = inHeight * 2.54;
int lbWeight = 180;
double kgWeight = lbWeight / 2.2;
System.out.println("He's " + inHeight + " inches (or " + cmHeight + " cm) tall.");
System.out.println("He's " + lbWeight + " pounds (or " + kgWeight + " kg) heavy.");
}
Note: two of the variables are doubles, so if you want to correctly format those to two decimal places, you'll have to use "printf" instead of "println".

You're writing text instead of a variable's value:
System.out.println( "He's " + Height + " inches or + (Height * 2.54) cm tall "." );
Change it to:
System.out.println( "He's " + Height + " inches or (" + (Height * 2.54) + " cm) tall.");
The same goes for the weight line:
System.out.println( "He's " + Weight + " pounds or + (Weight * 2.20) kg heavy "." );
Should be:
System.out.println( "He's " + Weight + " pounds or (" + (Weight * 2.20) + " kg) heavy.");
And please follow Java naming conventions:
Except for variables, all instance, class, and class constants are in mixed case with a lowercase first letter. Internal words start with capital letters. Variable names should not start with underscore _ or dollar sign $ characters, even though both are allowed.
From the above: variable names should start with a lower case
You should also read How to concatenate characters in Java

This might answer your question, it is a bit vague, so I am mostly guessing.
System.out.println( "He's " + Height + " inches or (" + Height * 2.54 + ") cm tall." );
You had formatted your println pretty badly. It is the same for the later one, I suggest having a look at it and figuring that one out by yourself.
Also I have no clue of what unit of measurement you are using for your Weight and Height, I recommend a double for this scenario. If you want more precision you have to look up on BigDecimal.
Normally variables and fields are written in lowerCamelCase in Java.

try this:
System.out.println( "He's " + Height + " inches or " + (Height * 2.54) + " cm tall "." );

Double Height = 74D; // inches
Double Weight = 180D; // pounds
System.out.println( "He's " + Height + " inches or " + (Height * 2.54) + " cm tall "." );
System.out.println( "He's " + Weight + " pounds or " + (Weight * 2.20) + " kg heavy "." );

Related

Where does the 1/72 PDFBox value come from?

I'm extracting images from the PDF page using the PDFBox. In the example I used as a basis (PrintImageLocations), the value of 72 dpi is used for calculation. My question is, where does this value 72 come from?
// position in user space units. 1 unit = 1/72 inch at 72 dpi
System.out.println("position in PDF = " + ctmNew.getTranslateX() + ", " + ctmNew.getTranslateY() + " in user space units");
// raw size in pixels
System.out.println("raw image size = " + imageWidth + ", " + imageHeight + " in pixels");
// displayed size in user space units
System.out.println("displayed size = " + imageXScale + ", " + imageYScale + " in user space units");
// displayed size in inches at 72 dpi rendering
imageXScale /= 72;
imageYScale /= 72;
System.out.println("displayed size = " + imageXScale + ", " + imageYScale + " in inches at 72 dpi rendering");
// displayed size in millimeters at 72 dpi rendering
imageXScale *= 25.4;
imageYScale *= 25.4;
System.out.println("displayed size = " + imageXScale + ", " + imageYScale + " in millimeters at 72 dpi rendering");
Not the most technical of answers... but its been a "standard" for some time... one that is arbitrary and rather silly... Here's a random article that talks about its silliness.
https://petapixel.com/2020/02/13/why-wont-the-72dpi-myth-die/
PDF is closer to being a collection of pixels like a bitmap, than it is to being a token based document like a text file. So for sizing elements on the screen/page it has to assume certain resolution... Because 72dpi was so prevalent for images for so long it makes sense that pdf followed suit.

Turning dark color to bright in java

I am working on a program where I take RGB values from a portion of an image. I want to remove the darkness in the color and make it bright. What I do is I use Color.RGBtoHSB I then take the brightness channel and set it to the highest value it can be in range then convert the HSB back to RGB. However, when I do this the color changes completely. Here is an example with dark red and it turning to purple and the code I use to do this.
System.out.println("Before Conversion:");
System.out.println("R: " + rAvg + "\nG :" + gAvg + "\nB :" + bAvg);
Color.RGBtoHSB(rAvg, gAvg, bAvg, hsv);
hsv[2] = 100; //Set to max value
System.out.println("H: " + hsv[0] * 360 + "\nS: " + hsv[1] * 100 + "\nV :" + hsv[2]);
int rgb = Color.HSBtoRGB(hsv[0], hsv[1], hsv[2]);
System.out.println("After conversion");
Color color = new Color(rgb);
System.out.println("R: " + color.getRed());
System.out.println("G: " + color.getGreen());
System.out.println("B: " + color.getBlue());
Output:
Before Conversion:
R: 128
G :39
B :50
H: 352.58426
S: 69.53125
V :100.0
After conversion
R: 158
G: 126
B: 233
The brightness, hsv[2], needs to be a value between 0 and 1. Try these two lines of code:
hsv[2] = 1; //Set to max value
System.out.println("H: " + hsv[0] * 360 + "\nS: " + hsv[1] * 100 + "\nV :" + hsv[2] * 100);

Making an RGB get closest colour algorithm more accurate

I've created a huge list of colours with names and RGB values (Took a very long time) now I've created an algorithm that gets the corresponding colour to the closest values.
It seems to work very well BUT sometimes when there's an odd value that's completely out it gets the wrong colour.
Example output
Log: InputRGB: R:7.1009636 | G:83.84344 | B:2.5013387
Log: ColorToCompare: Ball Blue (R13.0,G67.0,B80.0) CLOSE:0.4588677 | CurrentColor: Acid Green CLOSE: 0.41585693
Log: ColorToCompare: Bitter Lemon (R79.0,G88.0,B5.0) CLOSE:0.5143066 | CurrentColor: Ball Blue CLOSE: 0.4588677
Log: ColorToCompare: Citrine (R89.0,G82.0,B4.0) CLOSE:0.5610447 | CurrentColor: Bitter Lemon CLOSE: 0.5143066
Log: ColorToCompare: Smoky Black (R6.0,G5.0,B3.0) CLOSE:0.57945675 | CurrentColor: Citrine CLOSE: 0.5610447
Log: ColorName:Smoky Black
Log: End Color: R:6.0 G:5.0 B:3.0
Log: InputRGB: R:7.1009636 | G:83.84344 | B:2.5013387
The code I've created to calculate this:
public String getClosetColor(float red, float green, float blue){
Functions.log("InputRGB: R:" + red + " | G:" + green + " | B:" + blue);
Color lastColor = null;
for(Color eachColor : this.colors)
{
if(lastColor == null){
lastColor = eachColor;
}
float lastColorCloseness = (getClose(red, lastColor.red) + getClose(green, lastColor.green) + getClose(blue, lastColor.blue)) / 3f;
float thisColorCloseness = (getClose(red, eachColor.red) + getClose(green, eachColor.green) + getClose(blue, eachColor.blue)) / 3f;
if(Float.isFinite(thisColorCloseness) && Float.isFinite(lastColorCloseness))
{
//If they are the same, choose a random one.
if(lastColorCloseness == thisColorCloseness){
if(MathUtils.random() > 0.5f){
lastColor = eachColor;
}
}
//If this one is greater then set it.
else if(thisColorCloseness > lastColorCloseness){
Functions.log(
"ColorToCompare: " + eachColor.nameOfColor + " (R" + eachColor.red + ",G" + eachColor.green + ",B" + eachColor.blue + ") CLOSE:" + thisColorCloseness +
" | CurrentColor: " + lastColor.nameOfColor + " CLOSE: " + lastColorCloseness
);
lastColor = eachColor;
}
}
}
Functions.log("ColorName:" + lastColor.nameOfColor);
Functions.log("End Color: R:" + lastColor.red + " G:" + lastColor.green + " B:" + lastColor.blue);
Functions.log("InputRGB: R:" + red + " | G:" + green + " | B:" + blue);
return "";
}
//Basically if one is higher than the other then devide by it.
private float getClose(float firstNumber, float secondNumber){
if(firstNumber < secondNumber){
return firstNumber / secondNumber;
}
else{
return secondNumber / firstNumber;
}
}
I don't know how you came up with your distance function but it's a bit awkward. Let me explain:
You use the ratio of colors instead of the difference like:
float lastColorCloseness = (getClose(red, lastColor.red) + getClose(green, lastColor.green) + getClose(blue, lastColor.blue)) / 3f;
This has the strange effect of not applying equally to equally distanced colors. For example compare
col1(100, 50, 200) with col2(50, 100, 150) and col3(150, 100, 250).
Well, assuming that col2 and col3 have distance from col1 equals:
abs(100-50)+abs(50-100)+abs(200-150)=150
abs(100-150)+abs(50-100)+abs(200-250)=150
your distance function is giving different results:
(50/100+50/100+150/250)/3=0.53
(50/100+50/100+200/250)/3=0.6
And as #David Wallace mentioned it's not the most exaggerated results.
Use a distance function like Euclidean instead.
This is happening because your getClose method isn't doing a good job. If two numbers are both very small, the gap between them is greatly exaggerated.
You'd be much better off doing something like
1 / ( 1 + ( firstNumber - secondNumber ) * ( firstNumber - secondNumber ))
in getClose.
For defining a measure of "closeness", you would need to adjust for human eyes color perception plus possibly the display device.
First, a distance of X in one channel is worse than a distance of X/2 in two channels (a change in tone is more apparent than a comparable change in brightness). The larger a single channel distance the less "similar" the color is. Simply adding differences doesn't accout for that.
A simple to implement measure of distance is the difference between channels squared:
int deltaR = red1 - red2;
int deltaG = green1 - green2;
int deltaB = blue1 - blue2;
int distance = (deltaR * deltaR) + (deltaG * deltaG) + (deltaB * deltaB);
The human eye is not equally sensitive to each color channel. So you might want to adjust weighting color channels for that. A simple weighting can be derived from RGB to grayscale weigthing (Converting RGB to grayscale/intensity)
Modifying distance function for the weights gives:
float distance = (deltaR * deltaR) * 0.2989F
+ (deltaG * deltaG) * 0.5870F
+ (deltaB * deltaB) * 0.1140F;
That should provide a reasonable closeness function. Simply chose the color with smallest color distance.

How to get the size of the intersecting part in a circle in Java

I need the size of the black part of this image:
I've done some research about how to find it in normal math, and I was pointed to this website: Website
The final answer on getting it was
(from MathWorld - A Wolfram Web Resource: wolfram.com)
where r is the radius of the first circle, R the radius of the second circle, and d the distance between the two centers.
The code I tried to use to get the size of this was the following:
float r = getRadius1();
float R = e.getRadius1();
float deltaX = Math.abs((getX() + getRadius()) - (e.getX() + e.getRadius()));
float deltaY = Math.abs((getY() + getRadius()) - (e.getY() + e.getRadius()));
float d = (float) Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
float part, part2, part3;
//Chopping it in parts, because it's easier.
part = (float) (Math.pow(r,2) * Math.acos(
Math.toRadians((Math.pow(d, 2) + Math.pow(r, 2) - Math.pow(R, 2))/(2*d*r))));
part2 = (float) (Math.pow(R,2) * Math.acos(
Math.toRadians((Math.pow(d, 2) + Math.pow(R, 2) - Math.pow(r, 2))/(2*d*R))));
part3 = (float) (0.5 * Math.sqrt((-d + r + R) * (d+r-R) * (d-r+R) * (d+r+R)));
float res = part + part2 - part3;
Main.log(res + " " + part + " " + part2 + " " + part3+ " "
+ r + " " + R + " " + d);
//logs the data and System.out's it
I did some testing, and the output was this:
1345.9663 621.6233 971.1231 246.78008 20.0 25.0 43.528286
So that indicates that the size of the overlapping part was bigger than the circle itself (which is r^2 * PI).
What did I do wrong?
Just a guess (as stated in my comment): try removing the Math.toRadians(...) conversion.
Since there are no degrees involved in the formula but rather radii, I assume the parameter to cos-1(...) is already a value in radians.
If I remove the conversion and run your code, I get the following overlap area size: 11.163887023925781 which seems plausible since the length of the overlap segment on the line between the two centers is 20 + 25 - 43.5 = 1.5 (approximated)
Edit:
If I set the distance to 5 (the smaller circle is completely contained in the bigger one but touches its edge) I get the overlap area size 1256.63 which is exactly the area of the smaller circle (202 * Π). The calculation doesn't seem to work if the distance is smaller than the difference of the radii (i.e. in your case smaller than 5), but that might just be a problem of numerical representation (the normal datatypes might not be able to represent some of the intermediate results).

Can't get java to round 24.9999 properly, rounds to 8.?

I'm learning java and have a bit of code I am trying to write that should round 24.9999999 to 25. Instead, it goes to 8.
import java.io.*;
import java.util.*;
public class RadiusOfCircle
{
public static void main(String args[])
{
Scanner kbInput = new Scanner(System.in);
System.out.print("What is the area? _");
double area = kbInput.nextInt();
System.out.println("Radius of your circle is " + Math.sqrt( area / Math.PI));
double radius = Math.sqrt( area / Math.PI);
System.out.println("\nChecking your work now...\n area = pi*(r^2)\n " + area + " = 3.14 * (" + radius + ")^2");
double radiusSqrd = Math.pow(radius, 2);
System.out.println(" " + area + " = 3.14 * " + radiusSqrd);
System.out.println(" " + area + " = " + Math.PI * radiusSqrd);
System.out.println(area + " = " + (Math.round(radiusSqrd)));
System.out.println("Are the two values the same? \nIf yes, your code is correct! \nIf no, try again!");
}
}
Also, when it asks for keyboard input of what the area is, I put in 25.
This is the output:
What is the area? _25
Radius of your circle is 2.8209479177387813
Checking your work now...
area = pi*(r^2)
25.0 = 3.14 * (2.8209479177387813)^2
25.0 = 3.14 * 7.957747154594766
25.0 = 24.999999999999996
25.0 = 8
Are the two values the same?
If yes, your code is correct!
If no, try again!
You're rounding radiusSquared only, rather than Math.PI * radiusSquared. Fixing that should get the result you expect.
System.out.println(" " + area + " = " + Math.PI * radiusSqrd);
System.out.println(area + " = " + (Math.round(radiusSqrd)));
Shouldn't that be:
double value = Math.PI * radiusSqrd;
System.out.println(" " + area + " = " +value );
System.out.println(area + " = " + (Math.round(value )));
You omitted to multiply by PI:
System.out.println(area + " = " + Math.round(Math.PI * radiusSqrd));
Executing this gives the expected result.
float and double were designed for engineering problems, which have large positive powers of 10.. they cannot express negative powers of 10 accurately. In such cases use BigDecimal.
Run this simple code from Joshua Bloch's book Effective Java to get a sense of the extend of inaccuracy when dealing with negative powers and using double to store them. The answer should acutally be zero, but turns out to be something else entirely!
double funds = 1.00;
int itemsBought = 0;
for (double price = .10; funds >= price; price += .10) {
funds -= price;
itemsBought++;
}
System.out.println(itemsBought + ” items bought.”);
System.out.println(“Change: $” + funds);
}
If you want "accurate" math in Java, you should use the BigDecimal class, rather than either of the built-in floating point primitive types. double and float are always going to have issues like this, due to the nature of floating point arithmetic.
Please note that the recommended constructor for BigDecimal uses a String, not any of the numeric types. Since you are getting input from the console, this should be easy to implement.
You can use something like this:
double d = 10.938;
BigDecimal bd = new BigDecimal(d);
bd = bd.setScale(0,BigDecimal.ROUND_HALF_UP);
System.out.println(bd);
bd = new BigDecimal(d);
bd = bd.setScale(1,BigDecimal.ROUND_HALF_UP);
System.out.println(bd);
bd = new BigDecimal(d);
bd = bd.setScale(2,BigDecimal.ROUND_HALF_UP);
System.out.println(bd);
or like this:
double d = 10.938;
DecimalFormat decimalFormat = new DecimalFormat("#");
System.out.println(decimalFormat.format(d));
decimalFormat = new DecimalFormat("#.#");
System.out.println(decimalFormat.format(d));
decimalFormat = new DecimalFormat("#.##");
System.out.println(decimalFormat.format(d));

Categories