How to prevent scientific display of a float? - java

I have the following output
output =4.08E-4
output =8.9E-5
output =0.978461
output =0.224577
Now the thing I don't get is for 4.08E-4 - I assume it is a negative exponential and given <0 it returns true but is there another way of displaying this in decimal format?

Most likely you are trying to print a float/double using System.out.println(...).
This eventually calls the public static String toString() method of Float (or Double). Either way, if you read the Javadoc it states:
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).
You can get around this using System.out.printf(), like this:
double d = 0.000408;
System.out.println(d);
System.out.printf("%f", d);
This prints:
4.08E-4
0,000408
My 2 cents.

System.out.println(4.08e-4);
0.000408

I use NumberFormat class-
double d = 0.000408;
//For considering 4 digits after decimal place
NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(4);
nf.setGroupingUsed(false);
System.out.println(d);
System.out.println(nf.format(d));

I think what you're looking for is either the class NumberFormat or the printf function, either one would work.

Related

java removing trailing decimal digits causing .0 become .99

I want to simply have a function that converts a double with as many decimal places into 4 decimal places without rounding.
I have this code that has been working fine but found a random instance where it turned .0 into .99
Here are some sample outputs
4.12897456 ->4.1289
4.5 ->4.5
4.5231->4.5231
5.53->5.53
5.52->5.199 (Wrong conversion, I want it to be 5.52)
private static double get4Donly(double val){
double converted = ((long)(val * 1e4)) / 1e4;
return converted
}
EDIT: This conversion is called thousands of times, so please suggest a method where I dont have to create a new string all the time.
You can use DecimalFormat
import java.text.DecimalFormat;
import java.math.RoundingMode;
import java.util.Arrays;
public class MyClass {
public static void main(String args[]) {
DecimalFormat df = new DecimalFormat("#.####");
df.setRoundingMode(RoundingMode.DOWN);
for (Number n : Arrays.asList(4.12897456, 4.5, 4.5231, 5.53, 5.52)) {
Double d = n.doubleValue();
System.out.println(df.format(d));
}
}
}
RoundingMode.DOWN rounds towards zero, new DecimalFormat("#.####") creates a DecimalFormat instance that formats numbers to a maximum of 4 decimal places. Put those two together and the above code produces the following output, which I believe matches your expectations:
4.1289
4.5
4.5231
5.53
5.52
Doubles just don't work like you think they do.
They are stored in a binary form, not a decimal form. Just like '1 divided by 3' is not representable in a decimal double (0.3333333333 is not enough, it's infinite 3s, so not representable, so you get a rounding error), but '1 divided by 5' is representable just fine, there are numbers that are representable, and numbers that end up rounded when storing things in a double type, but crucially things that seem perfectly roundable in decimal may not be roundable in binary.
Given that they don't match up, your idea of 'eh, I will multiply by 4, turn it to a long, then convert back to a double, then divide by 1000' is not going to let those digits go through unmolested. This is not how you round things, as you're introducing additional loss in addition to the loss you already started out with due to using doubles.
You have 3 solutions available:
Just print it properly
A double cannot be considered to 'have 4 digits after the decimal separator' because a double isn't decimal.
Therefore, it doesn't even make sense to say: Please round this double to at most 4 fractional digits.
That is the crucial realisation. Once you understand that you'll be well along the way :)
What you CAN do is 'please take this double and print it by using no more than 4 digits after the decimal separator'.
String out = String.format("%.4f", 5.52);
or you can use System.printf(XXX) which is short for System.print(String.format(XXX)).
This is probably what you want
forget doubles entirely
For some domains its better to ditch doubles and switch to longs or ints. For example, if you're doing finances, it's better to store the atomic unit as per that currency in a long, and forego doubles instead. So, for dollars, store cents-in-a-long. For euros, the same. For bitcoin, store satoshis. Write custom rendering to render back in a form that is palatable for that currency:
long value = 450; // $4.50
String formatCurrency(long cents) {
return String.format("%s%s%d.%02d", cents < 0 ? "-" : " ", "$", Math.abs(cents) / 100, Math.abs(cents) % 100);
}
Use BigDecimal
This is generally more trouble than it is worth, but it stores every digit, decimally - it represent everything decimal notation can (and it also cannot represent anything else - 1 divided by 3 is impossible in BigDecimal).
I would recommend using the .substring() method by converting the double to a String. It is much easier to understand and achieve since you do not require the number to be rounded.
Moreover, it is the most simple out of all the other methods, such as using DecimalFormat
In that case, you could do it like so:
private static double get4Donly(double val){
String num = String.valueOf(val);
return Double.parseDouble(num.substring(0, 6));
}
However, if the length of the result is smaller than 6 characters, you can do:
private static double get4Donly(double val){
String num = String.valueOf(val);
if(num.length()>6) {
return Double.parseDouble(num.substring(0, 6));
}else {
return val;
}
}

Not able to print exact value of Double data Type variable [duplicate]

I want to print a double value in Java without exponential form.
double dexp = 12345678;
System.out.println("dexp: "+dexp);
It shows this E notation: 1.2345678E7.
I want it to print it like this: 12345678
What is the best way to prevent this?
Java prevent E notation in a double:
Five different ways to convert a double to a normal number:
import java.math.BigDecimal;
import java.text.DecimalFormat;
public class Runner {
public static void main(String[] args) {
double myvalue = 0.00000021d;
//Option 1 Print bare double.
System.out.println(myvalue);
//Option2, use decimalFormat.
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(8);
System.out.println(df.format(myvalue));
//Option 3, use printf.
System.out.printf("%.9f", myvalue);
System.out.println();
//Option 4, convert toBigDecimal and ask for toPlainString().
System.out.print(new BigDecimal(myvalue).toPlainString());
System.out.println();
//Option 5, String.format
System.out.println(String.format("%.12f", myvalue));
}
}
This program prints:
2.1E-7
.00000021
0.000000210
0.000000210000000000000001085015324114868562332958390470594167709350585
0.000000210000
Which are all the same value.
Protip: If you are confused as to why those random digits appear beyond a certain threshold in the double value, this video explains: computerphile why does 0.1+0.2 equal 0.30000000000001?
http://youtube.com/watch?v=PZRI1IfStY0
You could use printf() with %f:
double dexp = 12345678;
System.out.printf("dexp: %f\n", dexp);
This will print dexp: 12345678.000000. If you don't want the fractional part, use
System.out.printf("dexp: %.0f\n", dexp);
0 in %.0f means 0 places in fractional part i.e no fractional part. If you want to print fractional part with desired number of decimal places then instead of 0 just provide the number like this %.8f. By default fractional part is printed up to 6 decimal places.
This uses the format specifier language explained in the documentation.
The default toString() format used in your original code is spelled out here.
In short:
If you want to get rid of trailing zeros and Locale problems, then you should use:
double myValue = 0.00000021d;
DecimalFormat df = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
df.setMaximumFractionDigits(340); // 340 = DecimalFormat.DOUBLE_FRACTION_DIGITS
System.out.println(df.format(myValue)); // Output: 0.00000021
Explanation:
Why other answers did not suit me:
Double.toString() or System.out.println or FloatingDecimal.toJavaFormatString uses scientific notations if double is less than 10^-3 or greater than or equal to 10^7
By using %f, the default decimal precision is 6, otherwise you can hardcode it, but it results in extra zeros added if you have fewer decimals. Example:
double myValue = 0.00000021d;
String.format("%.12f", myvalue); // Output: 0.000000210000
By using setMaximumFractionDigits(0); or %.0f you remove any decimal precision, which is fine for integers/longs, but not for double:
double myValue = 0.00000021d;
System.out.println(String.format("%.0f", myvalue)); // Output: 0
DecimalFormat df = new DecimalFormat("0");
System.out.println(df.format(myValue)); // Output: 0
By using DecimalFormat, you are local dependent. In French locale, the decimal separator is a comma, not a point:
double myValue = 0.00000021d;
DecimalFormat df = new DecimalFormat("0");
df.setMaximumFractionDigits(340);
System.out.println(df.format(myvalue)); // Output: 0,00000021
Using the ENGLISH locale makes sure you get a point for decimal separator, wherever your program will run.
Why using 340 then for setMaximumFractionDigits?
Two reasons:
setMaximumFractionDigits accepts an integer, but its implementation has a maximum digits allowed of DecimalFormat.DOUBLE_FRACTION_DIGITS which equals 340
Double.MIN_VALUE = 4.9E-324 so with 340 digits you are sure not to round your double and lose precision.
You can try it with DecimalFormat. With this class you are very flexible in parsing your numbers.
You can exactly set the pattern you want to use.
In your case for example:
double test = 12345678;
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(0);
System.out.println(df.format(test)); //12345678
I've got another solution involving BigDecimal's toPlainString(), but this time using the String-constructor, which is recommended in the javadoc:
this constructor is compatible with the values returned by Float.toString and Double.toString. This is generally the preferred way to convert a float or double into a BigDecimal, as it doesn't suffer from the unpredictability of the BigDecimal(double) constructor.
It looks like this in its shortest form:
return new BigDecimal(myDouble.toString()).stripTrailingZeros().toPlainString();
NaN and infinite values have to be checked extra, so looks like this in its complete form:
public static String doubleToString(Double d) {
if (d == null)
return null;
if (d.isNaN() || d.isInfinite())
return d.toString();
return new BigDecimal(d.toString()).stripTrailingZeros().toPlainString();
}
This can also be copied/pasted to work nicely with Float.
For Java 7 and below, this results in "0.0" for any zero-valued Doubles, so you would need to add:
if (d.doubleValue() == 0)
return "0";
Java/Kotlin compiler converts any value greater than 9999999 (greater than or equal to 10 million) to scientific notation ie. Epsilion notation.
Ex: 12345678 is converted to 1.2345678E7
Use this code to avoid automatic conversion to scientific notation:
fun setTotalSalesValue(String total) {
var valueWithoutEpsilon = total.toBigDecimal()
/* Set the converted value to your android text view using setText() function */
salesTextView.setText( valueWithoutEpsilon.toPlainString() )
}
This will work as long as your number is a whole number:
double dnexp = 12345678;
System.out.println("dexp: " + (long)dexp);
If the double variable has precision after the decimal point it will truncate it.
I needed to convert some double to currency values and found that most of the solutions were OK, but not for me.
The DecimalFormat was eventually the way for me, so here is what I've done:
public String foo(double value) //Got here 6.743240136E7 or something..
{
DecimalFormat formatter;
if(value - (int)value > 0.0)
formatter = new DecimalFormat("0.00"); // Here you can also deal with rounding if you wish..
else
formatter = new DecimalFormat("0");
return formatter.format(value);
}
As you can see, if the number is natural I get - say - 20000000 instead of 2E7 (etc.) - without any decimal point.
And if it's decimal, I get only two decimal digits.
I think everyone had the right idea, but all answers were not straightforward.
I can see this being a very useful piece of code. Here is a snippet of what will work:
System.out.println(String.format("%.8f", EnterYourDoubleVariableHere));
the ".8" is where you set the number of decimal places you would like to show.
I am using Eclipse and it worked no problem.
Hope this was helpful. I would appreciate any feedback!
The following code detects if the provided number is presented in scientific notation. If so it is represented in normal presentation with a maximum of '25' digits.
static String convertFromScientificNotation(double number) {
// Check if in scientific notation
if (String.valueOf(number).toLowerCase().contains("e")) {
System.out.println("The scientific notation number'"
+ number
+ "' detected, it will be converted to normal representation with 25 maximum fraction digits.");
NumberFormat formatter = new DecimalFormat();
formatter.setMaximumFractionDigits(25);
return formatter.format(number);
} else
return String.valueOf(number);
}
This may be a tangent.... but if you need to put a numerical value as an integer (that is too big to be an integer) into a serializer (JSON, etc.) then you probably want "BigInterger"
Example:
value is a string - 7515904334
We need to represent it as a numerical in a Json message:
{
"contact_phone":"800220-3333",
"servicer_id":7515904334,
"servicer_name":"SOME CORPORATION"
}
We can't print it or we'll get this:
{
"contact_phone":"800220-3333",
"servicer_id":"7515904334",
"servicer_name":"SOME CORPORATION"
}
Adding the value to the node like this produces the desired outcome:
BigInteger.valueOf(Long.parseLong(value, 10))
I'm not sure this is really on-topic, but since this question was my top hit when I searched for my solution, I thought I would share here for the benefit of others, lie me, who search poorly. :D
use String.format ("%.0f", number)
%.0f for zero decimal
String numSring = String.format ("%.0f", firstNumber);
System.out.println(numString);
I had this same problem in my production code when I was using it as a string input to a math.Eval() function which takes a string like "x + 20 / 50"
I looked at hundreds of articles... In the end I went with this because of the speed. And because the Eval function was going to convert it back into its own number format eventually and math.Eval() didn't support the trailing E-07 that other methods returned, and anything over 5 dp was too much detail for my application anyway.
This is now used in production code for an application that has 1,000+ users...
double value = 0.0002111d;
String s = Double.toString(((int)(value * 100000.0d))/100000.0d); // Round to 5 dp
s display as: 0.00021
This will work not only for a whole numbers:
double dexp = 12345678.12345678;
BigDecimal bigDecimal = new BigDecimal(Double.toString(dexp));
System.out.println("dexp: "+ bigDecimal.toPlainString());
My solution:
String str = String.format ("%.0f", yourDouble);
For integer values represented by a double, you can use this code, which is much faster than the other solutions.
public static String doubleToString(final double d) {
// check for integer, also see https://stackoverflow.com/a/9898613/868941 and
// https://github.com/google/guava/blob/master/guava/src/com/google/common/math/DoubleMath.java
if (isMathematicalInteger(d)) {
return Long.toString((long)d);
} else {
// or use any of the solutions provided by others, this is the best
DecimalFormat df =
new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
df.setMaximumFractionDigits(340); // 340 = DecimalFormat.DOUBLE_FRACTION_DIGITS
return df.format(d);
}
}
// Java 8+
public static boolean isMathematicalInteger(final double d) {
return StrictMath.rint(d) == d && Double.isFinite(d);
}
This works for me. The output will be a String.
String.format("%.12f", myvalue);
Good way to convert scientific e notation
String.valueOf(YourDoubleValue.longValue())

Displayed precision of Java floating-point

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.

How do I print a double value without scientific notation using Java?

I want to print a double value in Java without exponential form.
double dexp = 12345678;
System.out.println("dexp: "+dexp);
It shows this E notation: 1.2345678E7.
I want it to print it like this: 12345678
What is the best way to prevent this?
Java prevent E notation in a double:
Five different ways to convert a double to a normal number:
import java.math.BigDecimal;
import java.text.DecimalFormat;
public class Runner {
public static void main(String[] args) {
double myvalue = 0.00000021d;
//Option 1 Print bare double.
System.out.println(myvalue);
//Option2, use decimalFormat.
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(8);
System.out.println(df.format(myvalue));
//Option 3, use printf.
System.out.printf("%.9f", myvalue);
System.out.println();
//Option 4, convert toBigDecimal and ask for toPlainString().
System.out.print(new BigDecimal(myvalue).toPlainString());
System.out.println();
//Option 5, String.format
System.out.println(String.format("%.12f", myvalue));
}
}
This program prints:
2.1E-7
.00000021
0.000000210
0.000000210000000000000001085015324114868562332958390470594167709350585
0.000000210000
Which are all the same value.
Protip: If you are confused as to why those random digits appear beyond a certain threshold in the double value, this video explains: computerphile why does 0.1+0.2 equal 0.30000000000001?
http://youtube.com/watch?v=PZRI1IfStY0
You could use printf() with %f:
double dexp = 12345678;
System.out.printf("dexp: %f\n", dexp);
This will print dexp: 12345678.000000. If you don't want the fractional part, use
System.out.printf("dexp: %.0f\n", dexp);
0 in %.0f means 0 places in fractional part i.e no fractional part. If you want to print fractional part with desired number of decimal places then instead of 0 just provide the number like this %.8f. By default fractional part is printed up to 6 decimal places.
This uses the format specifier language explained in the documentation.
The default toString() format used in your original code is spelled out here.
In short:
If you want to get rid of trailing zeros and Locale problems, then you should use:
double myValue = 0.00000021d;
DecimalFormat df = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
df.setMaximumFractionDigits(340); // 340 = DecimalFormat.DOUBLE_FRACTION_DIGITS
System.out.println(df.format(myValue)); // Output: 0.00000021
Explanation:
Why other answers did not suit me:
Double.toString() or System.out.println or FloatingDecimal.toJavaFormatString uses scientific notations if double is less than 10^-3 or greater than or equal to 10^7
By using %f, the default decimal precision is 6, otherwise you can hardcode it, but it results in extra zeros added if you have fewer decimals. Example:
double myValue = 0.00000021d;
String.format("%.12f", myvalue); // Output: 0.000000210000
By using setMaximumFractionDigits(0); or %.0f you remove any decimal precision, which is fine for integers/longs, but not for double:
double myValue = 0.00000021d;
System.out.println(String.format("%.0f", myvalue)); // Output: 0
DecimalFormat df = new DecimalFormat("0");
System.out.println(df.format(myValue)); // Output: 0
By using DecimalFormat, you are local dependent. In French locale, the decimal separator is a comma, not a point:
double myValue = 0.00000021d;
DecimalFormat df = new DecimalFormat("0");
df.setMaximumFractionDigits(340);
System.out.println(df.format(myvalue)); // Output: 0,00000021
Using the ENGLISH locale makes sure you get a point for decimal separator, wherever your program will run.
Why using 340 then for setMaximumFractionDigits?
Two reasons:
setMaximumFractionDigits accepts an integer, but its implementation has a maximum digits allowed of DecimalFormat.DOUBLE_FRACTION_DIGITS which equals 340
Double.MIN_VALUE = 4.9E-324 so with 340 digits you are sure not to round your double and lose precision.
You can try it with DecimalFormat. With this class you are very flexible in parsing your numbers.
You can exactly set the pattern you want to use.
In your case for example:
double test = 12345678;
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(0);
System.out.println(df.format(test)); //12345678
I've got another solution involving BigDecimal's toPlainString(), but this time using the String-constructor, which is recommended in the javadoc:
this constructor is compatible with the values returned by Float.toString and Double.toString. This is generally the preferred way to convert a float or double into a BigDecimal, as it doesn't suffer from the unpredictability of the BigDecimal(double) constructor.
It looks like this in its shortest form:
return new BigDecimal(myDouble.toString()).stripTrailingZeros().toPlainString();
NaN and infinite values have to be checked extra, so looks like this in its complete form:
public static String doubleToString(Double d) {
if (d == null)
return null;
if (d.isNaN() || d.isInfinite())
return d.toString();
return new BigDecimal(d.toString()).stripTrailingZeros().toPlainString();
}
This can also be copied/pasted to work nicely with Float.
For Java 7 and below, this results in "0.0" for any zero-valued Doubles, so you would need to add:
if (d.doubleValue() == 0)
return "0";
Java/Kotlin compiler converts any value greater than 9999999 (greater than or equal to 10 million) to scientific notation ie. Epsilion notation.
Ex: 12345678 is converted to 1.2345678E7
Use this code to avoid automatic conversion to scientific notation:
fun setTotalSalesValue(String total) {
var valueWithoutEpsilon = total.toBigDecimal()
/* Set the converted value to your android text view using setText() function */
salesTextView.setText( valueWithoutEpsilon.toPlainString() )
}
This will work as long as your number is a whole number:
double dnexp = 12345678;
System.out.println("dexp: " + (long)dexp);
If the double variable has precision after the decimal point it will truncate it.
I needed to convert some double to currency values and found that most of the solutions were OK, but not for me.
The DecimalFormat was eventually the way for me, so here is what I've done:
public String foo(double value) //Got here 6.743240136E7 or something..
{
DecimalFormat formatter;
if(value - (int)value > 0.0)
formatter = new DecimalFormat("0.00"); // Here you can also deal with rounding if you wish..
else
formatter = new DecimalFormat("0");
return formatter.format(value);
}
As you can see, if the number is natural I get - say - 20000000 instead of 2E7 (etc.) - without any decimal point.
And if it's decimal, I get only two decimal digits.
I think everyone had the right idea, but all answers were not straightforward.
I can see this being a very useful piece of code. Here is a snippet of what will work:
System.out.println(String.format("%.8f", EnterYourDoubleVariableHere));
the ".8" is where you set the number of decimal places you would like to show.
I am using Eclipse and it worked no problem.
Hope this was helpful. I would appreciate any feedback!
The following code detects if the provided number is presented in scientific notation. If so it is represented in normal presentation with a maximum of '25' digits.
static String convertFromScientificNotation(double number) {
// Check if in scientific notation
if (String.valueOf(number).toLowerCase().contains("e")) {
System.out.println("The scientific notation number'"
+ number
+ "' detected, it will be converted to normal representation with 25 maximum fraction digits.");
NumberFormat formatter = new DecimalFormat();
formatter.setMaximumFractionDigits(25);
return formatter.format(number);
} else
return String.valueOf(number);
}
This may be a tangent.... but if you need to put a numerical value as an integer (that is too big to be an integer) into a serializer (JSON, etc.) then you probably want "BigInterger"
Example:
value is a string - 7515904334
We need to represent it as a numerical in a Json message:
{
"contact_phone":"800220-3333",
"servicer_id":7515904334,
"servicer_name":"SOME CORPORATION"
}
We can't print it or we'll get this:
{
"contact_phone":"800220-3333",
"servicer_id":"7515904334",
"servicer_name":"SOME CORPORATION"
}
Adding the value to the node like this produces the desired outcome:
BigInteger.valueOf(Long.parseLong(value, 10))
I'm not sure this is really on-topic, but since this question was my top hit when I searched for my solution, I thought I would share here for the benefit of others, lie me, who search poorly. :D
use String.format ("%.0f", number)
%.0f for zero decimal
String numSring = String.format ("%.0f", firstNumber);
System.out.println(numString);
I had this same problem in my production code when I was using it as a string input to a math.Eval() function which takes a string like "x + 20 / 50"
I looked at hundreds of articles... In the end I went with this because of the speed. And because the Eval function was going to convert it back into its own number format eventually and math.Eval() didn't support the trailing E-07 that other methods returned, and anything over 5 dp was too much detail for my application anyway.
This is now used in production code for an application that has 1,000+ users...
double value = 0.0002111d;
String s = Double.toString(((int)(value * 100000.0d))/100000.0d); // Round to 5 dp
s display as: 0.00021
This will work not only for a whole numbers:
double dexp = 12345678.12345678;
BigDecimal bigDecimal = new BigDecimal(Double.toString(dexp));
System.out.println("dexp: "+ bigDecimal.toPlainString());
My solution:
String str = String.format ("%.0f", yourDouble);
For integer values represented by a double, you can use this code, which is much faster than the other solutions.
public static String doubleToString(final double d) {
// check for integer, also see https://stackoverflow.com/a/9898613/868941 and
// https://github.com/google/guava/blob/master/guava/src/com/google/common/math/DoubleMath.java
if (isMathematicalInteger(d)) {
return Long.toString((long)d);
} else {
// or use any of the solutions provided by others, this is the best
DecimalFormat df =
new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
df.setMaximumFractionDigits(340); // 340 = DecimalFormat.DOUBLE_FRACTION_DIGITS
return df.format(d);
}
}
// Java 8+
public static boolean isMathematicalInteger(final double d) {
return StrictMath.rint(d) == d && Double.isFinite(d);
}
This works for me. The output will be a String.
String.format("%.12f", myvalue);
Good way to convert scientific e notation
String.valueOf(YourDoubleValue.longValue())

What are the Java primitive data type modifiers?

Alright, I've been programming in Java for the better part of three years, now, and consider myself very experienced. However, while looking over the Java SE source code, I ran into something I didn't expect:
in class Double:
public static final double MIN_NORMAL = 0x1.0p-1022; // 2.2250738585072014E-308
public static final double MIN_VALUE = 0x0.0000000000001P-1022; // 4.9e-324
I did not expect this and can't find out what it means. If you don't know, I'm referring to the p and P that are after these numbers, before the subtraction operator. I know you can use suffixes to force a number to be a double, long, float, etc., but I've never encountered a p or P. I checked the Java API, but it doesn't mention it. Is there a complete list of Java primitive number literal modifiers somewhere? Does anyone know them all?
For reference, below are the ones I've used or encountered, with the ones whose purposes elude me in bold with question marks (# represents any arbitrary number within respective limits):
Suffixes:
# = 32-bit integer int
#L = 64-bit integer long
#l = another 64-bit integer l?
#f = 32-bit floating-point float
#F = another 32-bit floating-point float?
#d = 64-bit floating-point double
#D = another 64-bit floating-point double?
#e# = scientific notation
#E# = another scientific notation?
#p = ?
#P = ?
Any more?
Prefixes:
0b# = binary (base 2) literal
0B# = another binary (base 2) literal?
0# = octal (base 8) literal
# = decimal (base 10) literal
0x# = hexadecimal (base 16) literal
0X# = another hexadecimal (base 16) literal?
Any more?
Other (are there suffixes or prefixes for these?):
(byte)# = 8-bit integer byte
(short)# = 16-bit integer short
(char)# - 32-bit character char
P is the exponent. It does not matter if it's capital or not.
According to the Javadoc for toHextString (which we know is being used because it begins with 0x:
public static String toHexString(double d) Returns a hexadecimal string representation of the double 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 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 string "Infinity"; thus, positive infinity produces the result "Infinity" and negative
infinity produces the result "-Infinity".
If m is zero, it is represented by the string "0x0.0p0"; thus, negative zero produces the result "-0x0.0p0" and positive zero produces the result "0x0.0p0".
If m is a double value with a normalized representation, substrings are used to represent the significand and exponent fields. The significand is represented by the characters "0x1." followed by a lowercase hexadecimal representation of the rest of the significand as a fraction. Trailing zeros in the hexadecimal representation are removed unless all the digits are zero, in which case a single zero is used. Next, the exponent is represented by "p" followed by a decimal string of the unbiased exponent as if produced by a call to Integer.toString on the exponent value.
If m is a double value with a subnormal representation, the significand is represented by the characters "0x0." followed by a hexadecimal representation of the rest of the significand as a fraction. Trailing zeros in the hexadecimal representation are removed. Next, the exponent is represented by "p-1022". Note that there must be at least one nonzero digit in a subnormal significand.
According to the JLS, the following pieces of grammar are accepted:
3.10.1. Integer Literals
IntegerTypeSuffix:
l
L
OctalNumeral:
0 OctalDigits
0 Underscores OctalDigits
HexNumeral:
0 x HexDigits
0 X HexDigits
BinaryNumeral:
0 b BinaryDigits
0 B BinaryDigits
3.10.2. Floating-Point Literals
ExponentIndicator: one of
e
E
FloatTypeSuffix: one of
f
F
d
D
HexSignificand:
HexNumeral
HexNumeral .
0 x HexDigitsopt . HexDigits
0 X HexDigitsopt . HexDigits
BinaryExponentIndicator: one of
p
P
No other single character literals are specified for those purposes.
All of the legal ways to declare a literal are defined in the JLS.
p or P is the binary exponent of a number.
l or L defines a long.
f or F defines a float.
d or D defines a double.
0B or 0b defines a binary literal.
0x or 0X defines a hexadecimal literal.
e or E is also an exponent, but since e is a valid character in hexadecimal, p is also used.
P or p is a BinaryExponentIndicator. See the Java language specification.
See http://docs.oracle.com/javase/specs/jls/se5.0/html/lexical.html#3.10.2

Categories

Resources