I am trying to write some text to a file using PrintWriter and I do not understand what "7" means in the next example:
double d = 12.11211;
out.format(“%7.3f”, d);
The source from where I am inspiring says that 7 means:
The 7.3 before the f denotes the width (7) and precision (3) to output
d in.
The problem is that I cannot understand what that width really means. I mean, even though my variable would have more than 7 digits, it is not going to format anything.
Think of it as the total length of the string produced by the applied format.
If you take in account that there will be exactly 3 chars after the decimal point and 1 char for the decimal point itself, then it leaves 3 chars for the integer part.
Because your number has only 2 digits in the integer part the final result will be padded at the left with a white space:
double d = 12.11211;
out.format("%7.3f", d);
will create:
" 12.112"
with
out.format("%8.3f", d);
you get
" 12.112"
and so on.
The minimum length of the formatted string is in your case:
6 = 2 chars for the integer part + 1 char for the decimal point + 3 chars for the digits after the decimal point
so even if you set:
out.format("%5.3f", d);
this will not truncate the result, it will be:
"12.112"
For simple text arguments, you can think of the width and precision as a minimum and maximum number of characters to be output. For floating-point numeric types, the precision changes meaning slightly and controls the number of digits displayed after the decimal point.
watch this example:
System.out.printf("String is '%5s'\n", "A");
// String is ' A'
System.out.printf("String is '%.5s'\n", "Happy Birthday!");
// String is 'Happy'
for more information look at this link
Your source of inspiration should be the javadoc. It says:
The width is the minimum number of characters to be written to the
output. If the length of the converted value is less than the width
then the output will be padded by ' ' ('\u0020') until the total
number of characters equals the width. The padding is on the left by
default.[...]
For the floating-point conversions 'a', 'A', 'e', 'E', and 'f' the precision is the number of digits after the radix point.
A simple experiment shows it:
System.out.printf("%7.3f%n", 1.3);
System.out.printf("%7.3f%n", 12.3);
System.out.printf("%7.3f%n", 12.34);
System.out.printf("%7.3f%n", 12.345);
System.out.printf("%7.3f%n", 12.3456);
System.out.printf("%7.3f%n", 12.34567);
System.out.printf("%7.3f%n", 12.34567);
System.out.printf("%7.3f%n", 123.34567);
System.out.printf("%7.3f%n", 1234.34567);
System.out.printf("%7.3f%n", 12345.34567);
prints:
1,300
12,300
12,340
12,345
12,346
12,346
12,346
123,346
1234,346
12345,346
By width, it means the string will always fill the rest of the places if the number of digits/characters of the value is less than the given number.
double d = 12.11211;
String.format(“%7.3f”, d);
> 12.112
^^^^^^^
1234567
According to this:
The field width in a formatting operator is a nonnegative integer that
specifies the number of digits or characters in the output when
formatting input values. For example, in the operator %7.3f, the field
width is 7.
By default, the output text is padded with space
characters when the field width is greater than the number of
characters.
The 7 adds padding () in case the output is smaller than 7 characters. This way the output is always at least 7 characters, with 3 floating decimals.
This documentation gives a very detailed explanation for formatting text in general, most of which is applicable cross-language.
Related
I have one integer number and my goal is, to sum up digits in that integer
I tried with charAt(); but the weird part is when I'm trying to check numbers with their
index its works well but the part I don't understand is when I'm trying to sum them up
why 2 + 2 is 100
Scanner scanner = new Scanner(System.in);
int number = scanner.nextInt();
String string_number = Integer.toString(number);
System.out.println(string_number.charAt(0));
System.out.println(string_number.charAt(1));
System.out.println(string_number.charAt(0) + string_number.charAt(1));
input 22
Output
2
2
100
A character in Java is close to its unicode code point. And the unicode code point of '2' is... 0x32 or 50!
And yes, 50 + 50 is 100...
Fortunately, the value of a decimal digit is guaranteed to be c - '0', so what you want is:
System.out.println((string_number.charAt(0) - '0') + (string_number.charAt(1) - '0'));
You are calculating the sum of the ASCII values of the characters.
The ASCII value of the character '2' is 50. You are therefore adding 50 and 50.
You need to convert the character to the number first.
If we run the following code:
float f = 1.2345678990922222f;
double d = 1.22222222222222222222d;
System.out.println("f = " + f + "\t" + "d = " + d);
it prints:
f = 1.2345679 d = 1.2222222222222223
The long tail in the literal 1.2345678990922222 is ignored but the long tail in 1.22222222222222222222 is not (the last decimal digit in the variable d becomes 3 instead of 2). Why?
The number of digits you see when a float or a double is printed is a consequence of Java’s rules for default conversion of float and double to decimal.
Java’s default formatting for floating-point numbers uses the fewest significant decimal digits needed to distinguish the number from nearby representable numbers.1
In your example, 1.2345678990922222f in source text is converted to the float value 1.2345678806304931640625, because, of all the values representable in the float type, that one is closest to 1.2345678990922222. The next lower and next higher values are 1.23456776142120361328125 and 1.23456799983978271484375.
When printing this value, Java only needs to print “1.2345679”, because that is enough that we can pick out the float value 1.2345678806304931640625 from its neighbors 1.23456776142120361328125 and 1.23456799983978271484375.
For your double example, 1.22222222222222222222d is converted to 1.22222222222222232090871330001391470432281494140625. The next lower and next higher values representable in double are 1.2222222222222220988641083749826066195964813232421875 and 1.2222222222222225429533182250452227890491485595703125. As you can see, to distinguish 1.22222222222222232090871330001391470432281494140625 from its neighbors, Java needs to print “1.2222222222222223”.
Footnote
1 The rule for Java SE 10 can be found in the documentation for java.lang.float, in the toString(float d) section. The double documentation is similar. The passage, with the most relevant part in bold, is:
Returns a string representation of the float argument. All characters mentioned below are ASCII characters.
If the argument is NaN, the result is the string "NaN".
Otherwise, the result is a string that represents the sign and magnitude (absolute value) of the argument. If the sign is negative, the first character of the result is '-' ('\u002D'); if the sign is positive, no sign character appears in the result. As for the magnitude m:
If m is infinity, it is represented by the characters "Infinity"; thus, positive infinity produces the result "Infinity" and negative infinity produces the result "-Infinity".
If m is zero, it is represented by the characters "0.0"; thus, negative zero produces the result "-0.0" and positive zero produces the result "0.0".
If m is greater than or equal to 10-3 but less than 107, then it is represented as the integer part of m, in decimal form with no leading zeroes, followed by '.' ('\u002E'), followed by one or more decimal digits representing the fractional part of m.
If m is less than 10-3 or greater than or equal to 107, then it is represented in so-called "computerized scientific notation." Let n be the unique integer such that 10n ≤ m < 10n+1; then let a be the mathematically exact quotient of m and 10n so that 1 ≤ a < 10. The magnitude is then represented as the integer part of a, as a single decimal digit, followed by '.' ('\u002E'), followed by decimal digits representing the fractional part of a, followed by the letter 'E' ('\u0045'), followed by a representation of n as a decimal integer, as produced by the method Integer.toString(int).
How many digits must be printed for the fractional part of m or a? There must be at least one digit to represent the fractional part, and beyond that as many, but only as many, more digits as are needed to uniquely distinguish the argument value from adjacent values of type float. That is, suppose that x is the exact mathematical value represented by the decimal representation produced by this method for a finite nonzero argument f. Then f must be the float value nearest to x; or, if two float values are equally close to x, then f must be one of them and the least significant bit of the significand of f must be 0.
I am trying to write following code.but it gives me error kindly help me.
int six=06;
int seven=07;
int abc=018;
int nine=011;
System.out.println("Octal 011 ="+nine);
System.out.println("octal O18 =" + abc);
why i cant give 018 and 019 to variable.i can give value 020 and 021 to variable.
Why this happen? what's the reason behind this Kindly tell me.
I got Following error
integer number too large: 018
int eight=018;
Octal is base-8 number system, so it means digit can be from 0 to 7, you can't use digit 8 (and 9 too) in octal number system.
// Decimal declaration and possible chars are [0-9]
int decimal = 495;
// HexaDecimal declaration starts with 0X or 0x and possible chars are [0-9A-Fa-f]
int hexa = 0X1EF;
// Octal declaration starts with 0 and possible chars are [0-7]
int octal = 0757;
// Binary representation starts with 0B or 0b and possible chars are [0-1]
int binary = 0b111101111;
If the number is string format then you can convert it into int using the below
String text = "0b111101111";
int value = text.toLowerCase().startsWith("0b") ? Integer.parseInt(text.substring(2), 2)
: Integer.decode(text);
why i cant give 018 and 019 to variable.
Because an integer literal prefixed with 0 is treated as octal, and '8' and '9' aren't valid octal digits.
From section 3.10.1 of the JLS:
An octal numeral consists of an ASCII digit 0 followed by one or more of the ASCII digits 0 through 7 interspersed with underscores, and can represent a positive, zero, or negative integer.
Trying to use '8' in an octal number is like trying to use 'G' in hex... it's simple not part of the set of symbols used in that base.
Octal numbers (base 8) can only use the following figures: 01234567. The same way that decimal numbers (base 10) can only use 0123456789.
So in octal representation, 17 + 1 is 20.
The prefix 0 indicates octal(8 base)(digits 0-7).
public class MainClass{
public static void main(String[] argv){
int intValue = 034; // 28 in decimal
int six = 06; // Equal to decimal 6
int seven = 07; // Equal to decimal 7
int eight = 010; // Equal to decimal 8
int nine = 011; // Equal to decimal 9
System.out.println("Octal 010 = " + eight);
}
}
why i cant give 018 and 019 to variable.i can give value 020 and 021 to variable.
The leading zero signifies an octal literal. However, 8 and 9 are not valid octal digits. This makes 018 and 019 invalid.
When an integer literal starts with 0 in Java, it's assumed to be in octal notation. The digits 8 and 9 are illegal in octal—the digits can range only between 0 and 7.
Because it's octal, an octal number has 8 digits which spans from 0 to 7 inclusive. For the same reason 12 would be an invalid binary number.
You need at least base 9 to have 18 and a normal decimal base for 19.
For your query.....you assign an invalid value to the variable....your assigned value is started with 0(zero) ..which means that you are assigning an octal value to the variable and when you assign a value higher then 7 such as 018 in your case...the value excedes the range of octal variables and hence show an error...so try entering simply 18 so it would take it as an integer rather than an octal variable data type...
I have this code:
private String padWithZeroRightToPeriod(String serverFormat, float unformattedNumber, int index) {
int nDigits = getNumberOfDigitsAfterPeriod(serverFormat);
String floatingFormat = "%4." + nDigits + "f";
String formattedPrice = String.format(floatingFormat, unformattedNumber);
When called with unformattedNumber being 846, why is the result " 846" (a space and then the three digits)?
What does the %4. mean?
The docs for String.format refer you to this documentation on format strings, which says:
The format specifiers for general, character, and numeric types have the following syntax:
%[argument_index$][flags][width][.precision]conversion
The optional argument_index is a decimal integer indicating the position of the argument in the argument list. The first argument is referenced by "1$", the second by "2$", etc.
The optional flags is a set of characters that modify the output format. The set of valid flags depends on the conversion.
The optional width is a positive decimal integer indicating the minimum number of characters to be written to the output.
The optional precision is a non-negative decimal integer usually used to restrict the number of characters. The specific behavior depends on the conversion.
The required conversion is a character indicating how the argument should be formatted. The set of valid conversions for a given argument depends on the argument's data type.
From your example output, it appears that getNumberOfDigitsAfterPeriod is returing 0, so your format string is %4.0f. So:
It doesn't have an argument index (there's no $ after the 4)
It has a width (4)
It has a precision (0)
And of course it has a conversion (f)
So 846 is output as " 846" because the width is 4. The width in question is the total number of characters output. Here's a different example: Live Copy
public class Example {
public static void main(String args[]) {
System.out.println(String.format("%8.2f", 846.0));
System.out.println(String.format("%8.2f", 42.4));
}
}
Output:
846.00
42.40
Note that each of those is eight characters long.
I am wanting to store an integer named Amount, I want it to be stored in pence so if the user entered 11.45 it would be stored as 1145. What is the best way to remove the decimal point? Should I be using decimalFormatting in Java?
Edit:
It is entered in string format, was going to covert it to an int. I will give one of your solutions ago and let you know if it works but not sure which one would be the best.. Thanks everyone.
times it by 100 and cast as int. Use decimal formatting is double / float are too inaccurate which they may be for money
If the user input is in the form of a string (and the format has been verified), then you can strip out the decimal point and interpret the result as an integer (or leave it as a string without the decimal point).
String input = "11.45";
String stripped = input.replace(".", ""); // becomes "1145"
int value = Integer.parseInt(stripped);
If it's a float already, then just multiply by 100 and cast, as #user1281385 suggests.
What about convert to float, multiply by 100 and then convert to int?
String pound = "10.45"; // user-entered string
int pence = (int)Math.round(Float.parseFloat(pound) * 100);
This might be also useful: Best way to parseDouble with comma as decimal separator?
Tested and works. Even if the user enters a number without a decimal, it will keep it as such.
double x = 11.45; // number inputted
String s = String.valueOf(x); // String value of the number inputted
int index = s.indexOf("."); // find where the decimal is located
int amount = (int)x; // intialize it to be the number inputted, in case its an int
if (amount != x) // if the number inputted isn't an int (contains decimal)
// multiply it by 10 ^ (the number of digits after the decimal place)
amount = (int)(x * Math.pow(10,(s.length() - 1 - index)));
System.out.print(amount); // output is 1145
// if x was 11.4500, the output is 1145 as well
// if x was 114500, the output is 114500