With below code sample why the first addition (1/2+1/2) prints 0 but the second addition prints 00.
System.out.println(1/2+1/2+"=1/2+1/2");
System.out.println("1/2+1/2="+1/2+1/2);
Output:
0=1/2+1/2
1/2+1/2=00
Integer math (int 1 divided by int 2 is int 0, if you want a floating point result cast one, or both, of 1 and 2 to a floating point type) and order of operations, the second example is String concatenation. The compiler turns that into
System.out.println(new StringBuilder("1/2+1/2=").append(1/2).append(1/2));
and then you get
System.out.println(new StringBuilder("1/2+1/2=").append(0).append(0));
The first statement "System.out.println(1/2+1/2+"=1/2+1/2");" prints 0 because an the integer value obtained from 1/2 is zero. The remainder is dropped and since 1/2 equals 0.5 the .5 is dropped.
The second statement "System.out.println("1/2+1/2="+1/2+1/2);" prints out 00 because of the concatenation sign. In the second statement the first integer 1 is shown as +1 so the statement is actually being read as (+1/2 +1/2) which is why it returns 00.
If the second statement was set up like this:
System.out.println("1/2+1/2="+ (1/2+1/2));
The output would be the same as the first statement.
Expression is evaluated from left to right. In the first case it does int+int (which is 0), then int + "= String" which is a String tmp = "0= String". In the other case you have '"String =" + intwhich becomes"String =int"to which you append one moreint`. Thus you print String, "0" and "0".
java assumes that the result of the division is integer , since its members are integers. For the floating result ( 0.5 ) of each division , the divisor or the dividend should be of type float
System.out.println("1/2+1/2="+(1/2.0+1/2.0));
Related
I am obviously new to java. I have this assignment where I am supposed to write a program which performs arithmetic operations on numbers expressed as a character string.
I don't know where to start. I have tried googling, looking through my book, big java, in the relevant sections but can't seem to find helpful information.
I found a program that have completed the same assignment but I want to learn write my own and understand how to go about.
I can show you one of the methods that he used.
I have bolded a few comments where I get confused.
public static String add(String num1, String num2) {
while (num1.length() > num2.length()) {
num2 = "0" + num2;
}
while (num1.length() < num2.length()) {
num1 = "0" + num1;
}
int carry = 0; // whats the point of this?
String result = "";
// look at the for loop bellow. I don't understand why he is converting the strings to ints this
// way? this doesn't even return the correct inputed numbers?
for (int i = 1; i <= num1.length(); i++) {
int digit1 = Character.getNumericValue(num1.charAt(num1.length() - i));
int digit2 = Character.getNumericValue(num2.charAt(num2.length() - i));
int sum = digit1 + digit2 + carry;
carry = sum / 10;
result = (sum % 10) + result;
// why is he dividing the sum with 10? If the user inputs a 5, would't the result become 0.5
// which isn't a valid int value? this line is also confusing
}
if (carry > 0) {
result = carry + result;
}
return result;
}
Any explanation or even guidance to a page where I am trying to do is explained would be very appreciated.
I found a program that have completed the same assignment but I want to learn write my own and understand how to go about.
That is the right idea. I suggest that you stop looking at the code that you found. (I'm sure that your teachers don't want you to look up the answers on the internet, and you will learn more from your homework if you don't do it.)
So how to proceed?
(I am assuming that you are supposed to code the methods to do the arithmetic, and not just convert the entire string to a primitive number or BigInteger and use them to do the arithmetic.)
Here's my suggested approach:
What you are trying to program is the equivalent of doing long addition with a pencil and paper. Like you were taught in primary school. So I suggest that you think of that pencil-and-paper procedure as an algorithm and work out how to express it as Java code. The first step is to make sure that you have the steps of this algorithm clearly in your head.
Try to break the larger problem into smaller sub-problems. One sub-problem could be how to convert a character representing a decimal digit into an integer; e.g. how to convert '1' to 1. Next sub-problem is adding two numbers in the range 0 to 9 and dealing with the "carry". A final sub-problem is converting an integer in the range 0 to 9 into the corresponding character.
Write sample Java code fragments for each sub-problem. If you have been taught about writing methods, some of the code fragments could be expressed as Java methods.
Then you assemble the solutions to the sub-problems into a solution for the entire problem. For example, adding two (positive!) numbers represented as strings involves looping over the digits, starting at the "right hand" end.
As part of your program, write a collection of test cases that you can use to automate the checking. For example:
String test1 = add("8", "3");
if (!test1.equals("11")) {
System.out.println("test1 incorrect: expected '11' go '" +
test1 + "'");
}
Hints:
You can "explode" a String to a char[] using the toCharArray method. Or you could use charAt to get characters individually.
You can convert between a char representing a digit and an int using Character methods or with some simple arithmetic.
You can use + to concatenate a string and a character, or a character and a string. Or you can use a StringBuilder.
If you need to deal with signed numbers, strip off and remember the sign, do the appropriate computation, and put it back; e.g. "-123 + -456" is "- (123 + 456)".
If you need to do long multiplication and long division, you can build them up from long addition and long subtraction.
You can convert a number in String format to a number in numeric format by “long n = Long. parseLong(String)” or “Long n = Long.valueOf(String)”. Then just add 2 long variables using a + sign. It will throw NumberFormatException if the String is not a number but a character. Throw that exception back to the caller.
The first part of the code pads both numbers to equal lengths.
e.g. "45" + "789" will be padded to "045" + "789"
The for loop evaluates one character at a time, starting from the right hand most.
iteration 1 -> (right most)
5 + 9 -> 14
when you divide an integer with another integer, you will always get an integer.
hence carry = 14/10 = 1 (note: not 1.4, but 1, because an int cannot have decimal places)
and the remainder is 14 % 10 = 4 (mod operation)
we now concatenate this remainder into "result" (which is "" empty)
result = (14%10)+ result; // value of result is now "4"
iteration 2 -> (second right most)
4+8 + (carry) = 4 + 8 + 1 = 13
same thing, there is a carry of 13/10 = 1
and the remainder is 13%10 = 3
we concatenate the remainder into result ("4")
result = (13%10) + result = 3 +"4" = "34"
iteration 3->
0 + 7 + 1 = 8
this time 8/10 will give you 0 (hence carry = 0)
and 8%10 will give a remainder of 8.
result = 8 + "34" = "834"
after all the numbers have been evaluated, the code checks if there are anymore carry. if the value is more than 0, then that value is added to the front of the result.
I have a constant that's negative and I want the output to come out as positive. When I add a %+f it doesn't do anything and the output still comes out -15,123.45?
public static final double n2 = -15123.456789;
System.out.printf("%+,.2f\n", n2);
The format string "%+,.2f\n" only defines the formatting in which value must be printed. It doesn't change the actual value. If your input value is negative, the output string will display it as negative. It's like, when you make something bold, it doesn't change to another thing.
To convert the value to the opposite sign (- to +, + to -), you can multiply the value by -1: Thanks to kjbartel for the shortcut.
System.out.printf("%+,.2f\n", -1 * n2);
// or
System.out.printf("%+,.2f\n", -n2);
To convert the value to always be positive (- to +, + to +), you can use Math.abs: Thanks to zubergu for the tip.
System.out.printf("%+,.2f\n", Math.abs(n2));
I have a problem with remainder operator in java:
Why this:
(int)2147483648l % 10
gives a negative number (-8)?
That's because (int) 2147483648l is -2147483648. You're casting the long to int and it is out of bounds.
Casting problem .Data loss due to narrowing. You are converting long to int.
Read more about conversion.
From JLS
The remainder operation for operands that are integers after binary numeric promotion (§5.6.2) produces a result value such that (a/b)*b+(a%b) is equal to a.
from Narrowing Primitive Conversions JLS 5.1.3
So 2147483648l will cast into int that will be -2147483648 and then based on (a/b)*b+(a%b) = a
Value should be -8 what you are getting.
use "long" in place of "int".
you can use it without typecasting also
Following Example might be useful:
public class Example1
{
public static void main(String args[])
{
int b = (int)2147483648l;
System.out.println("Value of b: "+ b);
System.out.println("Output1: "+b % 10);
long a = 2147483648l;
System.out.println("Value of a: "+ a);
System.out.println("Output2: "+ a % 10);
}
}
output
Value of b: -2147483648
Output1: -8
Value of a: 2147483648
Output2: 8
You're getting a negative number because you're converting a long to an int. A possible work around in your case simply takes advantage of the fact that any decimal x mod 10 is simply the digit in the lowest decimal place (in the ones place). For example, 156 mod 10 is 6, because 156 divided by 10 is 15 + (6/10). So you could do something like this
//get the number and make it a string
String numberAsString = String.valueOf(number);
//get the integer value of the last character in the string (basically the lowest place)
int mod10 = Integer.parseInt(numberAsString.charAt(numberAsString.length() - 1));
This works for any integer number as long as what you want is number % 10
I'm attemping to compare some players with a comparator by the amount of runs they have obtained.
System.out.println("Comparing: " + p2.getRuns() + " and " + p1.getRuns());
int newRESULT = intConvert(p2.getRuns()).compareTo(intConvert(p1.getRuns()));
System.out.println("Returns: " + newRESULT);
return newRESULT;
However this returns:
Comparing: 25 and 0,
Returns: 2
Comparing: 0 and 100,
Returns: -1
Comparing: 25 and 100,
Returns: 1
...and hence orders the players in the wrong order.
Should the first comparison not return 1, the second -1 and the last -1 as well?
intConvert:
private static String intConvert(int x)
{
return "" + x;
}
I assume intConvert(...) converts an int to a String, and thus you get lexical comparisons which meahs "25" is greater than "100" because the first character is greater (2 > 1).
If you want to get correct comparisons stick to comparing ints or if you need to use a String create strings of equal length and fill in missings zeros at the front (e.g. 25 -> "025").
To compare Numbers that are represented as String in a sensible way, you need to consistently format them all the same way.
Strings use lexical comparisons. This means "5" will be > "20" because 5 is > than 2. To get the logically expected output you need to format the numbers with some kind of formatter to make them lexically comparable.
"05" is < "20"
The simplest thing would be to use String.format() and a pattern to format all the numbers to Strings so they will compare consistently lexically.
String.format("%04d", yourInteger);
This will produce all ints that are passed in as left padded with 0 for 4 positions.
String.format("%04d", 5);
will produce 0005
Make the "%0Xd" where X is the number of digits you want it formatted to.
You don't have to convert the numbers to strings just to sort, you can do something like:
class ComparePlayersByRuns implements Comparator<Player> {
public int compareTo(Player p1, Player p2) {
return p1.getRuns().compareTo(p2.getRuns());
}
}
or in Java 8 and later all you need to create your comparator is:
Comparators.comparing(Player::getRuns);
And no, the compare isn't required to return 1, 0, or -1, the documentation says:
Returns:
a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
Why does this code sometimes return 1E+1 whilst for other inputs (e.g. 17) the output is not printed in scientific notation?
BigDecimal bigDecimal = BigDecimal.valueOf(doubleValue).multiply(BigDecimal.valueOf(100d)).stripTrailingZeros();
System.out.println("value: " + bigDecimal);
use bigDecimal.toPlainString():
BigDecimal bigDecimal = BigDecimal.valueOf(100000.0)
.multiply(BigDecimal.valueOf(100d))
.stripTrailingZeros();
System.out.println("plain : " + bigDecimal.toPlainString());
System.out.println("scientific : " + bigDecimal.toEngineeringString());
outputs:
plain : 10000000
scientific : 10E+6
It's the implicit .toString() conversion that is happening when you pass the result into System.out.println().
The exact rationale for the behaviour of BigDecimal.toString() is explained in the API doc in great (and near incomprehensible) detail.
To get a consistent (and locale-sensitive) textual representation, you should use DecimalFormat.
It's basically because you don't have enough significant digits. If you multiply something that only has 1 significant digit with 100, then you get something with only 1 significant digit. If it shows "10" then that basically says that it has 2 significant digits. The way to show it only has 1 significant digit is to show "1 x 10^1".
The following two decimals have the same value (10), but different "scales" (where they start counting significant digits; the top has 2 sig figs, the bottom has 1):
System.out.println(new BigDecimal(BigInteger.TEN, 0)); // prints 10
System.out.println(new BigDecimal(BigInteger.ONE, -1)); // prints 1E+1