How to go about formatting 1000 Gram to 1 Kg [duplicate] - java

This question already has answers here:
Int division: Why is the result of 1/3 == 0?
(19 answers)
Closed 2 years ago.
I'd like to format following numbers into the numbers next to them with Android:
I've tried it, by taking the code from How to go about formatting 1200 to 1.2k in Android studio
This works when the value is a multiple of zero, but if there is a number other than zero some are not suitable
String numberString = "";
if (Math.abs(Integer.parseInt(weight_total) / 1000) > 1) {
numberString = (Integer.parseInt(weight_total) / 1000) + " kg";
}
else {
numberString = weight_total + " gram";
}
tvWeight.setText(": " + numberString);
I want to 1000 gram > 1 kg, 1800 gram > 1.8 kg etc
Correct and Wrong weight screenshot https://i.stack.imgur.com/mqA0x.jpg
Now i am using this code, so its work fine and perfect for my app
// Input data
int weightInput = Integer.parseInt(item.getWeight());
String weightOutput;
if (weightInput < 1000) {
weightOutput = weightInput + " gram";
} else {
double result = weightInput / 1000.0;
weightOutput = String.valueOf(result);
weightOutput = (weightOutput.contains(".0") ? weightOutput.substring(0, weightOutput.length() - 2) : weightOutput) + " kg";
}
System.out.println(weightOutput);
Final result https://i.stack.imgur.com/1Nxbs.png

Integer.parseInt convert String into int.
if you divide an int by int the result will be int too.
use Float.parseFloat() instead, or divide it by 1000.0 (make the 1000 non-integer value and then the result will be non-integer too.)
if you want it to be more precise and count milligrams (or even smaller units) you must use Float.parseFloat() because the value after the dot will be discarded using Integer.parseInt().

Here you go, I wrote a java code for this and I am sure it is going to work in android as well.
package stackOverflow;
import java.util.*;
import java.io.*;
public class parseWeight {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//Ignore above
//assuming you have int as input
int weightInput = Integer.parseInt(br.readLine());
String outputString = "";
if(weightInput < 1000){
outputString = weightInput + " gram";
}
else if(weightInput >= 1000){
double temp = weightInput / 1000.0;
//round off upto one decimal places
double rf = Math.round((temp*10.0)/10.0);
outputString = rf + " kg";
}
tvWeight.setText(": " + outputString);
//Ignore below
System.out.println(outputString);
}
}

Related

Java: Finding Percent Difference

I am trying to figure out how to find the percent difference between the original (no space) string of text and the disemvoweled (no space) string of text. I am attempting to do this by using the equation ((newAmount-reducedAmount)/reducedAmount) but I am having no luck and am ending up with a value of zero, as shown below.
Thank you!
My Code:
import java.util.Scanner;
public class Prog5 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner console = new Scanner(System.in);
System.out.println("Welcome to the disemvoweling utility!"); // Initially typed "disemboweling" xD
System.out.print("Enter text to be disemvoweled: ");
String inLine = console.nextLine();
String vowels= inLine.replaceAll("[AEIOUaeiou]", ""); // RegEx for vowel control
System.out.println("Your disemvoweled text is: " + vowels); // Prints disemvoweled text
// Used to count all characters without counting white space(s)
int reducedAmount = 0;
for (int i = 0, length = inLine.length(); i < length; i++) {
if (inLine.charAt(i) != ' ') {
reducedAmount++;
}
}
// newAmount is the number of characters on the disemvoweled text without counting white space(s)
int newAmount = 0;
for (int i = 0, length = vowels.length(); i < length; i++) {
if (vowels.charAt(i) != ' ') {
newAmount++;
}
}
int reductionRate = ((newAmount - reducedAmount) / reducedAmount); // Percentage of character reduction
System.out.print("Reduced from " + reducedAmount + " to " + newAmount + ". Reduction rate is " + reductionRate + "%");
}
}
My output: (Test string is without quotes: "Testing please")
Welcome to the disemvoweling utility!
Enter text to be disemvoweled: Testing please
Your disemvoweled text is: Tstng pls
Reduced from 13 to 8. Reduction rate is 0%
You used an integer data type while calculating percentage difference while performing integer division. You need to type cast one of the variables on the right hand side of the equation to perform double division and then store them in double. The reason for doing this is java integer type can't hold the real numbers.
Also, multiple it by 100 to get the percentage.
double reductionRate = 100 * ((newAmount - reducedAmount) / (double)reducedAmount);
If you want a fraction between 0 and 1, then
double reductionRate = ((newAmount - reducedAmount) / (double)reducedAmount);
Your formula gives you a value between zero and one.
An integer cannot hold fractions so it always shows zero.
Multiply by 100 to get a regular percentage value.
int reductionRate = 100*(newAmount - reducedAmount) / reducedAmount; // Percentage of character reduction

How to convert a location in Degrees Minutes Seconds represented as a String to Double

My app lets users search a location and one of the queries I got was
"78°14'09"N 15°29'29"E"
Obviously the user wants to go to this location.
First how do I check if this string fits the decimal format correctly. Then how do I convert it to double format?
double latitude = convertToDouble("78°14'09"N")
I searched here on stackoverflow but they are all looking for the opposite: double to decimal.
78°14'09"N 15°29'29"E
First how do I check if this string fits the decimal format correctly. Then how do I convert it to double format?
The string is not in decimal (degrees) format. It is in degrees, minutes, and seconds, which is more or less the opposite of decimal degrees format. I therefore interpret you to mean that you want to test whether the string is in valid D/M/S format, and if so, to convert it to decimal degrees, represented as a pair of doubles.
This is mostly a parsing problem, and regular expressions are often useful for simple parsing problems such as this one. A suitable regular expression can both check the format and capture the numeric parts that you need to extract. Here is one way to create such a pattern:
private final static Pattern DMS_PATTERN = Pattern.compile(
"(-?)([0-9]{1,2})°([0-5]?[0-9])'([0-5]?[0-9])\"([NS])\\s*" +
"(-?)([0-1]?[0-9]{1,2})°([0-5]?[0-9])'([0-5]?[0-9])\"([EW])");
That's a bit dense, I acknowledge. If you are not familiar with regular expressions then this is no place for a complete explanation; the API docs for Pattern provide an overview, and you can find tutorials in many places. If you find that your input matches this pattern, then not only have you verified the format, but you have also parsed out the correct pieces for the conversion to decimal degrees.
The basic formula is decimal = degrees + minutes / 60 + seconds / 3600. You have the additional complication that coordinates' direction from the equator / prime meridian might be expressed either via N/S, E/W or by signed N, E, or by a combination of both. The above pattern accommodates all of those alternatives.
Putting it all together, you might do something like this:
private double toDouble(Matcher m, int offset) {
int sign = "".equals(m.group(1 + offset)) ? 1 : -1;
double degrees = Double.parseDouble(m.group(2 + offset));
double minutes = Double.parseDouble(m.group(3 + offset));
double seconds = Double.parseDouble(m.group(4 + offset));
int direction = "NE".contains(m.group(5 + offset)) ? 1 : -1;
return sign * direction * (degrees + minutes / 60 + seconds / 3600);
}
public double[] convert(String dms) {
Matcher m = DMS_PATTERN.matcher(dms.trim());
if (m.matches()) {
double latitude = toDouble(m, 0);
double longitude = toDouble(m, 5);
if ((Math.abs(latitude) > 90) || (Math.abs(longitude) > 180)) {
throw new NumberFormatException("Invalid latitude or longitude");
}
return new double[] { latitude, longitude };
} else {
throw new NumberFormatException(
"Malformed degrees/minutes/seconds/direction coordinates");
}
}
The convert() method is the main one; it returns the coordinates as an array of two doubles, representing the coordinates in decimal degrees north and east of the intersection of the equator with the prime meridian. Latitudes south of the equator are represented as negative, as are longitudes west of the prime meridian. A NumberFormatException is thrown if the input does not match the pattern, or if the latitude or longitude apparently represented is invalid (the magnitude of the longitude cannot exceed 180°; that of the latitude cannot exceed 90°).
You won't be able to parse that into a double without removing the non number chars but,
String string = "78°14'09"N";
Double number = 0;
try{
number = Double.parseDouble(string);
//do something..
}catch (NumberFormatException e){
//do something.. can't be parsed
}
If you first remove any characters from the string that are not alphanumeric, then something along these lines will work. This code compiles.
public class HelloWorld{
public static void main(String []args){
String input = "78 14'09 N 15 29'29 E".replaceAll("[^A-Za-z0-9]", " ");
String[] array = input.split(" ");
int nDegree = Integer.parseInt(array[0]);
int nMinute = Integer.parseInt(array[1]);
int nSecond = Integer.parseInt(array[2]);
int eDegree = Integer.parseInt(array[4]);
int eMinute = Integer.parseInt(array[5]);
int eSecond = Integer.parseInt(array[6]);
double nDegrees = nDegree + (double) nMinute/60 + (double) nSecond/3600;
double eDegrees = eDegree + (double) eMinute/60 + (double) eSecond/3600;
String nResult = "Decimal = N " + Double.toString(nDegrees).substring(0,10);
String eResult = "Decimal = E " + Double.toString(eDegrees).substring(0,10);
System.out.println(nResult);
System.out.println(eResult);
}
}
Output:
Decimal = N 78.2358333
Decimal = E 15.4913888
The problem is that Java can't store the degrees ° character as part of a String, or internal quotes (the minute character). If you can find a way to remove them from the string before inputting the data, then this will work.
I don't have a solution for handling the degrees symbol, but you could use an escape symbol \" to allow the use of a quotation mark within a string.
So I've used a regex with capturing groups to grab each of the numbers and the N/S/E/W. After capturing each individually it's just a matter of doing a bit of dividing to get the numbers and then formatting them however you'd like. For example I went with 5 digits of precision here.
public static void main(String[] args) {
String coords = "78°14'09N 15°29'29E";
String[] decimalCoords = degreesToDecimal(coords);
System.out.println(decimalCoords[0]);
System.out.println(decimalCoords[1]);
}
public static String[] degreesToDecimal(String degMinSec) {
String[] result = new String[2];
Pattern p = Pattern.compile("(\\d+).*?(\\d+).*?(\\d+).*?([N|S|E|W]).*?(\\d+).*?(\\d+).*?(\\d+).*?([N|S|E|W]).*?");
Matcher m = p.matcher(degMinSec);
if (m.find()) {
int degLat = Integer.parseInt(m.group(1));
int minLat = Integer.parseInt(m.group(2));
int secLat = Integer.parseInt(m.group(3));
String dirLat = m.group(4);
int degLon = Integer.parseInt(m.group(5));
int minLon = Integer.parseInt(m.group(6));
int secLon = Integer.parseInt(m.group(7));
String dirLon = m.group(8);
DecimalFormat formatter = new DecimalFormat("#.#####", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
formatter.setRoundingMode(RoundingMode.DOWN);
result[0] = formatter.format(degLat + minLat / 60.0 + secLat / 3600.0) + " " + dirLat;
result[1] = formatter.format(degLon + minLon / 60.0 + secLon / 3600.0) + " " + dirLon;
}
return result;
}
There is no error handling here, it's just a basic example of how you could make this work with your input.

Show decimal of a double only when needed (rounding issue)

I am trying to get a desired output based on a variable input. I can get close to what I want but there seems to be an issue with rounding a number.
What I want by example (input > output).
30 > 30
30.0 > 30
30.5 > 30,5
30.5555 > 30,6
30.04 > 30
The problem is that the last one comes back as 30.0. Now I understand why this is happening (because of the rounding up/down)
My code:
private String getDistanceString(double distance) {
distance = 30.55;
DecimalFormat df = new DecimalFormat(".#");
if (distance == Math.floor(distance)) {
//If value after the decimal point is 0 change the formatting
df = new DecimalFormat("#");
}
return (df.format(distance) + " km").replace(".", ",");
}
It is almost always wrong to use == with floating point numbers. You should use Math.abs(a - b) < x.
private String getDistanceString(double distance) {
DecimalFormat df = new DecimalFormat(".#");
if (Math.abs(distance - Math.round(distance)) < 0.1d) {
//If value after the decimal point is 0 change the formatting
df = new DecimalFormat("#");
}
return (df.format(distance) + " km").replace(".", ",");
}
public void test() {
double[] test = {30d, 30.0d, 30.5d, 30.5555d, 30.04d, 1d / 3d};
for (double d : test) {
System.out.println("getDistanceString(" + d + ") = " + getDistanceString(d));
}
}
A hack around it, is to replace with regex
return
(""+df.format(distance))
.replaceAll("\\.(0+$)?", ",") //replace . and trailing 0 with comma,
.replaceAll(",$","") //if comma is last char, delete it
+ " km"; //and km to the string

Divide Euro Amount

I have a problem in my code and i can't find the answer for it.
I only can use if and else and can't use other classes for an example Math.
The code save a value and try to divide in euro coins.
If i enter 4,31 the result is 2x2e + 1x20c + 1x1c and this is ok but if i enter the value 1,20 the result is 1e + 1x10c + 1x5c + 2x2c + 1x1c but the right result is 1e + 1x20c.
I had to add 0.001 in the 1cent coin because if i don't i'll not get a print for it. Adding this is wrong too.
If somebody could help me i would be very grateful.
Regards.
Code:
import java.util.Scanner;
public class Coins {
public static void main(String[] args){
Scanner in= new Scanner(System.in);
int e2 = 0, e1 = 0,c50 = 0, c20=0,c10 = 0,c5 = 0,c2 = 0,c1;
double v;
System.out.println("Quantia em euros: ");
v = in.nextDouble();
e2 = (int)v/2;
v=v-e2*2;
e1=(int)v;
v=(v-e1)*100;
c50=(int)v/50;
v=v-c50*50;
c20=(int)v/20;
v=v-c20*20;
c10=(int)v/10;
v=v-c10*10;
c5=(int)v/5;
v=v-c5*5;
c2=(int)v/2;
v=v-c2*2;
c1=(int)(v+0.001);
if(e2!=0)System.out.print(e2+"X2Eur ");
if(e2!=0&&!(e1==0&&c50==0&&c20==0&&c10==0&&c5==0&&c2==0&&c1==0))System.out.print("+ ");
if(e1!=0)System.out.print(e1+"X1Eur ");
if(e1!=0&&!(c50==0&&c20==0&&c10==0&&c5==0&&c2==0&&c1==0))System.out.print("+ ");
if(c50!=0)System.out.print(c50+"X50c ");
if(c50!=0&&!(c20==0&&c10==0&&c5==0&&c2==0&&c1==0))System.out.print("+ ");
if(c20!=0)System.out.print(c20+"X20c ");
if(c20!=0&&!(c10==0&&c5==0&&c2==0&&c1==0))System.out.print("+ ");
if(c10!=0)System.out.print(c10+"X10c ");
if(c10!=0&&!((c5==0&&c2==0&&c1==0)))System.out.print("+ ");
if(c5!=0)System.out.print(c5+"X5c ");
if(c5!=0&&!(c2==0&&c1==0))System.out.print("+ ");
if(c2!=0)System.out.print(c2+"X2c ");
if(c2!=0&&!(c1==0))System.out.print("+ ");
if(c1!=0)System.out.print(c1+"X1c");
}
}
first of all: if you store a value in a double-variable, always consider that double is a bit imprecise, i'd use cents instead (simply remove the comma and parse to int).
for the implementation itself: optimize the whole thing using arrays.
final int[] coin_values = new int[]{
200 , 100 , 50 , 20 , 10 , 5 , 2 , 1};
final String[] coin_names = new String[]{
"2€" , "1€" , "50ct" , "20ct" , "10ct" , "5ct" , "2ct" , "1ct"};
String input = in.next();
String[] temp = input.split(".");
input = temp[0] + temp[1];
int value = Integer.parseInt(input);
int[] coins = new int[coin_values.length];
for(int i = 0 ; i < coins.length ; i++){
coins[i] = value / coin_values[i];
value %= coin_values[i];
if(coins[i] != 0)
System.out.print(coins[i] + " " + coin_names[i] + " + ");
}
These are rounding errors by Java, they can always occur when using floats. In your case you keep editting the same value so the error gets bigger and bigger.
Use
System.out.println("Quantia em euros: ");
v = 1.20;
int cents = (int)(v*100);
e2 = cents/200;
cents = cents%200;
e1=cents / 100;
cents = cents % 100;
c50=cents/50;
cents = cents%50;
c20=(int)cents/20;
cents = cents %20;
c10=(int)cents/10;
cents = cents%10;
c5=(int)cents/5;
cents = cents % 5;
c2=(int)cents/2;
c1=cents%2;
Because rounding errors don't occur on ints.
In Java always use java.math.BigDecimal for monetary amounts.
You won't get strange rounding behaviour that you can't control.

My code compiles but does not execute. Where did I go wrong? How can this be avoided in future codes?

I'm trying to convert any roman numeral under 3,999 to a decimal number. The code compiles but never prompts me to enter the roman numeral like the scanner asks it to.
//necessary for the scanner
import java.util.Scanner;
/**
* conversion of roman numerals into decimals
*
* #Annika Helverson
* period 5
*/
public class Numeral
{
private static Scanner scanner = new Scanner( System.in );
public static int decimalValue (String romanNumeral) {
int decimal = 0;
int count = 0;
int i = 1;
//tell user what to do
System.out.print( "Please enter a valid roman numeral: ");
//read the submitted number
String input = scanner.nextLine();
//display input back to user
System.out.println( "input =" + input );
while (count < romanNumeral.length ()-1 || i < romanNumeral.length ()){
if (romanNumeral.substring (count, i).equals ("M")){
decimal = decimal + 1000;
}
if (romanNumeral.substring (count, i).equals ("D")) {
decimal = decimal + 500;
}
if (romanNumeral.substring (count, i).equals ("C")) {
decimal = decimal + 100;
}
if (romanNumeral.substring (count, i).equals ("L")) {
decimal = decimal + 50;
}
if (romanNumeral.substring (count, i).equals ("X")) {
decimal = decimal + 10;
}
if (romanNumeral.substring (count, i).equals ("V")) {
decimal = decimal + 5;
}
if (romanNumeral.substring (count, i).equals ("I")) {
decimal = decimal + 1;
}
count = count + 1;
i = i + 1;
}
{
if (romanNumeral.contains ("CM")){
decimal = decimal - 200;
theres more code in here of all the "exceptions" in roman numerals.
}
return decimal;
}
}
}
You need a main method to serve as the entry point of your program. This class is only usable if you create an object of it and call it's methods on the newly created object.
What you need is the main method:
public static void main(String args[]) {
// Your code that should be executed on start, here
}
Don't throw all the code inside the main-method, though. That's bad practice.
Your method public static int decimalValue (String romanNumeral) gets passed a string that you should probably convert. You are using a Scanner inside your decimalValue method, but it's supposed to be called in main and pass the the numeral to your method. You are probably not calling your method from main at all.

Categories

Resources