Java: How do I set a maximum length for a Double? - java

How do I set a maximum length for a double?
double divSum = number1 / number2;
String divDisplay = number1 + " / " + number2 + " = " + divSum + " ";
JLabel divSumLabel= new JLabel();
divSumLabel.setText(divDisplay)
How do I set the maximum lenght for divSum?
1 / 3 = 0.333333... How do I set the maximum lenght, so its only 0.333?
I could do:
int maxLenght = 3;
String stringDivSum = String.valueOf(divSum);
String shortDivSum = null;
if(stringDivSum.length() > maxLenght){
shortDivSum = stringDivSum.substring(0, maxLenght);
}
String divDisplay = number1 + " / " + number2 + " = " + shortDivSum + " ";
But when I then do 1 / 3 it prints out 1 / 3 = 0.3?

Use String.format(...)
String.format()
double divSum = Double.parseDouble(String.format("%.3f",(double)number1 / number2)) ;
Precision, double.
We can specify the precision of a double or float. We use the "f" to
indicate a floating-point. Before this we specify ".3" to mean "three
numbers after the decimal."

double dblValue2 = Math.round( .333333 * 1000.0 ) / 1000.0;

this will help you
String.format("%.2f", (double)value);

You can try
System.out.format("%.2f + %.2f = %.2f",number1,number2,divsum)
You basically tell the formatter to expect 3 floats with 2 decimals with %.2f. It is important to supply the variables in order you want them to, so writing ,number1,number2,divsum will yield different results than writing ,number2,number1,divsum If you want to print int, short or long, you use %d. If you want to print string you use %s. But you can also google that.
Also, storing numeric data in String in case of mathematical operations is kind of pointless exercise and only bloats your code.

If you want to store the result of the division with a scale of 3 (i.e. 3 digits after the decimal point), you need to use a BigDecimal for this. This class allows to do arbitrary-precision calculus on decimal values.
int number1 = 1, number2 = 3;
BigDecimal divSum = BigDecimal.valueOf(number1).divide(BigDecimal.valueOf(number2), 3, RoundingMode.DOWN);
The divide(divisor, scale, roundingMode) function of BigDecimal can take a scale (here set to 3) and a rounding mode (here set to DOWN, this rounding mode truncates after the scale has been reached, which is what we want here). This will perform the division and the result will be rounded down with a scale of 3.
You can then print the result with:
String divDisplay = number1 + " / " + number2 + " = " + divSum + " ";
System.out.println(divDisplay); // prints "1 / 3 = 0.333"

Related

Java 8 any good rounding algorithm to round the bigdecimal and return total value as 100

I am currently looking for a good algorithm which will do the rounding and return the total value as 100. The variable type is BigDecimal.
I have to return the BigDecimal in 2 digit format e.g. 10.10
The result should be something like this:
List will have
18.56, 20.96, 18.56, 19.16 and 22.75.
Total of 18.56 + 20.96 + 18.56 + 19.16 + 22.75 should be 100.00
The rounding when done with these values should be very close to the original value. Must be as accurate as possible.
This will not be the only scenario there could be 3 ,4, 5, 6 upto 10 variables.
Any help will be appreciated.
I did the rounding of the arraylist.
Added all the values
Checked the difference
Now I am planning to reverse rounded sorting array and subtract the difference from first and 2nd so that it is equal to 100.
I am not very sure how good this algorithm is but I would really appreciate if you have any better idea.
#Test
public void roundDecimalValuesAndCalculateTotalToHundredPercent() {
BigDecimal no1 = BigDecimal.valueOf(18.562874251497007);
BigDecimal no2 = BigDecimal.valueOf(20.958083832335326);
BigDecimal no3 = BigDecimal.valueOf(18.562874251497007);
BigDecimal no4 = BigDecimal.valueOf(19.161676646706585);
BigDecimal no5 = BigDecimal.valueOf(22.75449101796407);
List<BigDecimal> value = Arrays.asList(no1, no2, no3, no4, no5);
scaleAndPrintList(value);
}
private void scaleAndPrintList(List<BigDecimal> list) {
list.forEach(bigDecimal -> {
System.out.println("Number is " + bigDecimal + ", ROUND_CEILING - " + bigDecimal.setScale(2, BigDecimal.ROUND_CEILING) + ", ROUND_HALF_UP - " + bigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP));
});
list = list.stream()
.map(bigDecimal -> bigDecimal.setScale(2, BigDecimal.ROUND_CEILING)).collect(Collectors.toList());
final BigDecimal reduce = list.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println("Addition " + reduce);
// This is the error.
final BigDecimal difference = BigDecimal.valueOf(100).subtract(reduce);
System.out.println("Difference - " + difference);
}
It depends, how do you want to sacrifice precision of members.
To do it in 1 pass, and spread the error across members, I would collect (rounded/dropped) part of each member and keep sum of rounded, than add dropped delta of previous to the next one before rounding. The last member must be calculated like this: 100 - (summ of prev) - which will be already rounded to 2 digits.
private static void scaleAndPrintList(List<BigDecimal> list) {
BigDecimal sum = BigDecimal.valueOf(0);
BigDecimal delta = BigDecimal.valueOf(0);
for(int i=0;i<list.size()-1;i++) {
BigDecimal bd = list.get(i);
BigDecimal res = bd.add(delta).setScale(2,BigDecimal.ROUND_HALF_UP);
System.out.println("Number " + bd + " => " + res + " diff: " + bd.subtract(res));
delta = bd.subtract(res);
sum = sum.add(res);
}
// Last member
BigDecimal bd = list.get(list.size()-1);
BigDecimal res = BigDecimal .valueOf(100).subtract(sum);
System.out.println("Last Number " + bd + " => " + res + " diff: " + bd.subtract(res));
}
Output:
Number 18.564474251497007 => 18.56 diff: 0.004474251497007
Number 20.954483832335328 => 20.96 diff: -0.005516167664672
Number 18.562874251497007 => 18.56 diff: 0.002874251497007
Number 19.161676646706585 => 19.16 diff: 0.001676646706585
Last Number 22.75449101796407 => 22.76 diff: -0.00550898203593

Can val be used as variable in Java?

Is the program legal or not?
I am trying to correct out a statement that will print the value of 3 divided by 2.
I know this isn't correct.
System.out.print("The result is" + 3 / 2 + ".")
This is my answer.
System.out.print("The result is" + val + ".")
double val = 3 / 2
Is my answer correct or no? If not, how would I call upon the number?
You can do the following
double val = 3.0 / 2;
System.out.print("The result is" + val + ".");
the value val must be declared before it is printed. Also you need to make one of the number of type double so when the division is done, the answer is a double also. Else you lose precision.
the following is also valid:
double val = 3 / 2.0;
System.out.print("The result is" + val + ".");
if you do double val = 3 / 2; then 3/2 division is made with two integers which also give another integer. So 3/2 should give 1.5 but since we are only diving integers, it will omit the .5 and only give 1. Then 1 is casted as a double and becomes 1.0.
What you have is mostly correct:
float val1 = 3;
float val2 = 2;
float val= val1/val2;
System.out.println("The result is " + val + ".");
Remember your semicolons.
Also... You are correct to use a double (or float). Because otherwise your answer will be truncated.
EDIT:
Actually... I come to find that trying to do the operation in one shot still truncates the answer. It isn't correct unless both the values are set as floats. Then, run the math.
Here is proof: online java compiler
You need to declare first the variables. And if you want fraction numbers you need to do that with them. Need " ; " at the end of every statement. If you try it out in eclipse it will sign error to you when you don't write it where it need to be.
float num1 = 3;
float num2 = 2;
float val = num1 / num2;
System.out.print("The result is" + val + ".");
// Another way:
double num1 = 3;
double num2 = 2;
double val = num1 / num2;
System.out.print("The result is" + val + ".");
This should work:
double val = 3.0 / 2;
System.out.print("The result is" + val + ".");
Edit:
This is a case of integer division. When division is performed between two integers (here 3 and 2), the output is an integer and the fractional part gets trimmed off. So,3/2 will yield 1 which since you assign to a double variable, becomes 1.0.
When I do 3.0/2, 3.0 is a double value. The output here is a double value too i.e. 1.5; the fractional part is retained. Hence, my solution works.

Double Accuracy

I need some help, this is the code I'm referring to:
int myId;
my Id = 20113275l
int numLet;
numLet = 6;
double doubleResult;
doubleResult = 10000 + (80 + ((myId - 123456) / ((numLet + 20)*(numLet + 20)) ));
System.out.println("Expression 5: " + doubleResult);
According to my calculator, the answer should be 39650.7, but when I run the program it's giving me 39650.0
Can anyone explain what's going on here?
You should use double values only to get the wanted result in this case :
int myId;
myId = 20113275;
int numLet;
Becomes
double myId = 20113275.0;
double numLet;
And here is the output :
Expression 5: 39650.73816568047
You're getting integer division, because none of your parameters are double. The result of dividing two integers is an integer. And your type is an int (adding an l at the end promotes to long). Anyway, cast one of the terms to a double and you'll get the result you expect. For one decimal of precision you can use formatted output. Something like,
public static void main(String[] args) {
int myId = 20113275; // <--- Not a long.
int numLet = 6;
double doubleResult = 10000 + //
(80 + ((myId - 123456) / (double) ((numLet + 20) * (numLet + 20))));
System.out.printf("Expression 5: %.1f%n", doubleResult);
}
Output is (as you requested)
Expression 5: 39650.7

Percentage always equal to 0 [duplicate]

This question already has answers here:
Int division: Why is the result of 1/3 == 0?
(19 answers)
Closed 9 years ago.
I have this method. It basically uses popup windows to display simple addition questions:
public static void addition ()
{
JFrame frame = new JFrame("");
JOptionPane.showMessageDialog(frame, "++ You chose Addition! ++");
double percentage;
String rank = "";
int i = 0;
int x = 0;
int y = 0;
while (true){
int add1 = (int)(Math.random()*9) + 1;
int add2 = (int)(Math.random()*9) + 1;
i = i + 1;
int addtotal = add1 + add2;
try{
String test = JOptionPane.showInputDialog(frame, i + "). What's " + add1 + " + " + add2 + "?");
if (test == null){
choose();
}
int convertToNum = Integer.parseInt (test);
if (convertToNum == addtotal){ // if the user got it right
x++;
final ImageIcon icon = new ImageIcon(new URL("http://cdn2.iconfinder.com/data/icons/basicset/tick_64.png")); //Custom Icon for the JFrame below, The image destination uses a URL link to show the icon
JOptionPane.showMessageDialog(null, "Nice Job!\nYou Currently Got " + x + " Out of " + i + " Correct!",":D",JOptionPane.INFORMATION_MESSAGE,icon);
}
else { // if the user got it wrong
JOptionPane.showMessageDialog(frame, "Sorry, but that was wrong.\n" + add1 + " + " + add2 + " = " + addtotal + " . \n You Currently Got " + x + " Out of " + i + " Correct!","Whoops",JOptionPane.INFORMATION_MESSAGE);
y++;
}
}
catch (Exception e){
JOptionPane.showMessageDialog(frame, "I Didn't Understand That.","...",JOptionPane.ERROR_MESSAGE);
y++;
}
System.out.println ("x: " +x);
System.out.println ("i: " +i);
percentage = (x - y) / i * 100;
System.out.println ("% :" + percentage);
}
}
Say I keep getting perfect, Then percentage = 100.0 when displayed on the interactions pane. HOWEVER when I get one question wrong, instead of getting a percentage number, i automatically get a zero (ex say I got 2 out of 3, percentage = 0 instead of percentage = 66.6. I tried getting rid of the 0 when declaring it, but it only gives me "variable may not have been initialized".
cast one of the integer operands inside the bracket to double to make use of floating point arithmetic .
double percentage = ((double)x - y) / i * 100;
All operands (x,y,i and literal 100) are integers, therefore integer arithmetic division is used which will remove everything after the decimal point.
The problem with dividing ints is Java truncates the decimal portion. You can either make x and y floating point variables or just cast them to float for doing the division and cast them back to get an int as the final result.
Welcome to integer arithmetic.
Try percentage = ((double)x - y) / i * 100;
From the Chapter 15 :
The type of a multiplicative expression is the promoted type of its
operands.
If the promoted type is int or long, then integer arithmetic
is performed. If the promoted type is float or double, then
floating-point arithmetic is performed.

Round down a double and compare to another number

I am trying to round down a double using Big decimal and then comparing to another number For example:
// Parse the string to extract the double and then put it into Big
// decimal
BigDecimal bdAns = BigDecimal.valueOf(Double.parseDouble("3.1419"));
System.out.println(bdAns);
BigDecimal bdCorr = BigDecimal.valueOf(Double.parseDouble("3.142"));
System.out.println(bdCorr);
System.out.println(bdCorr.precision() + " , " + bdAns.precision());
// Round down the value of the bdAns, so that the precision of bdAns and
// bdCorr matches. This code doesnt seem to work.
bdAns = BigDecimal.valueOf(bdAns).setScale(bdCorr.precision(),
BigDecimal.ROUND_UNNECESSARY);
System.out.println(bdAns);
System.out.println(bdAns.compareTo(bdCorr));
The last println is printing -1.But they should be equal as 3.1419 round to 3 places after decimal should be 3.142. Can somebody please tell me what is wrong with the code?
precision and scale are not the same thing, it appears you are confusing the two. scale is the number of digits to the right of the decimal point. precision is the total number of digits.
Change all of your references to precision to scale and it should work (but you'll have to pick a rounding mode other than UNNECESSARY).
Here's an whole example of what you're trying to achieve:
import java.math.*;
public class bigdec {
public static void main(String[] args) {
BigDecimal dec1 = new BigDecimal("3.1419");
BigDecimal dec2 = new BigDecimal("3.142");
System.out.println("first - " + dec1);
System.out.println("second - " + dec2);
MathContext mc = new MathContext(dec2.scale() + dec1.toString().indexOf("."));
dec1 = dec1.round(mc);
System.out.println("AFTER ROUNDING");
System.out.println("first - " + dec1);
System.out.println("second - " + dec2);
System.out.println(dec1.equals(dec2));
}
}
It rounds dec1 based on the number of decimal places in dec2.
I would use double and long
double d1 = 3.1419;
double d2 = 3.142;
long l1 = (long) (d1 * 100);
long l2 = (long) (d2 * 100);
// both l1 and l2 are 314
The problem you have is that you are using setScale() of a precision.
bdAns = bdAns.setScale(bdCorr.scale(), BigDecimal.ROUND_HALF_UP);

Categories

Resources