Java basic arithmetic and data type - java

Silly question but can't find the answer.
double divider = 1000;
List<Long> listLong = new ArrayList<>();
listLong.add(1500L);
listLong.add(8000L);
for (Long val : listLong)
{
System.out.println((val/ divider));
}
Gives me
1.5
8.0
and I want
1.5
8
distance and distance2 are Long and can't be changed.
divider has to be the same thing for both cases.
ANWSER:
Thanks to KevinO
DecimalFormat df = new DecimalFormat("#.##");
for (Long val : listLong)
{
System.out.println(df.format(val/ divider));
}

Try to use DecimalFormat like this:
DecimalFormat df = new DecimalFormat("###.#");
System.out.println(df.format(distance2 / divider));

You can use DecimalFormat to accomplish what you need. Going off of your updated question:
double divider = 1000;
List<Long> listLong = new ArrayList<>();
listLong.add(1500L);
listLong.add(8000L);
DecimalFormat df = new DecimalFormat("###.#");
for (Long val : listLong) {
System.out.println(df.format(val / divider));
}
Produces:
run:
1.5
8
BUILD SUCCESSFUL (total time: 0 seconds)

This is because one of the two parameters are of type double.
You can simply achieve what you are trying to achieve by adding a cast to integer by doing: System.out.println((int) (distance2 / divider));
Also, you should use primitives as it requires only a fraction of the memory. Replace Long with long.
Here is the corrected code snippet:
public static void main (String[] args) throws Exception
{
List<Long> listLong = new ArrayList<>();
listLong.add(1500L);
listLong.add(8000L);
double divider = 1000;
for (long val : listLong)
{
int calc = (int)(val/divider);
if((val/divider - calc) == 0) {
System.out.println(calc);
} else {
System.out.println(val/divider);
}
}
}
Output:
1.5
8

use DecimalFormat
what works for me:
public class NewClass {
public static void main(String[] args) {
DecimalFormat dcf= new DecimalFormat("#.#");
Long distance = 1500L;
Long distance2 = 8000L;
double divider = 1000;
System.out.println(dcf.format(distance / divider));
System.out.println(dcf.format(distance2 / divider));
}
}
output
1.5
8

Related

why java.math.BigDecimal.valueOf(double) does use new BigDecimal(String), instead of new BigDecimal(double)

Here is the code:
public static void main(String[] args) {
final double d1 = 811.440000;
final double d2 = 425.530000;
final double d3 = 384.270000;
for (double d : Arrays.asList(d1, d2, d3)) {
final String dstr = String.format("%f", d);
BigDecimal bg1 = BigDecimal.valueOf(d).setScale(2, BigDecimal.ROUND_DOWN);
BigDecimal bg2 = (new BigDecimal(dstr)).setScale(2, BigDecimal.ROUND_DOWN);
BigDecimal bg3 = (new BigDecimal(d)).setScale(2, BigDecimal.ROUND_DOWN);
System.out.printf("[%s : %f] {%f, %f} %f\n", dstr, d, bg1, bg2, bg3);
}
}
Here is the output:
[811.440000 : 811.440000] {811.440000, 811.440000} 811.440000
[425.530000 : 425.530000] {425.530000, 425.530000} 425.520000
[384.270000 : 384.270000] {384.270000, 384.270000} 384.260000
Why don't we change valueOf(double) method or the BigDecimal(double) constructor of the BigDecimal class so as to get a consistent result?
The problem here isn't that one of new BigDecimal(double) nor new BigDecimal(String) working false.
The problem here is, that double are not precise. They store their bits in a way, which can't represent all numbers.
Here are some links about that topic:
Whats wrong with this simple 'double' calculation?
https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems
Retain precision with double in Java
slightly change the code:
public static void main(String[] args) {
final double d1 = (new Double("811.44")).doubleValue();
final double d2 = (new Double("425.53")).doubleValue();
final double d3 = (new Double("384.27")).doubleValue();
final double DD = (new Double("999999999999999.95")).doubleValue(); // 15 9s before decimal point
for (double d : Arrays.asList(d1, d2, d3)) {
final String dstr = String.valueOf(d);
BigDecimal bg1 = BigDecimal.valueOf(d);
BigDecimal bg2 = (new BigDecimal(dstr));
BigDecimal bg3 = (new BigDecimal(d));
System.out.printf("* [%s : %s : %.15f] {%.15f, %.15f, %.15f}\n", dstr, d, d, bg1, bg2, bg3);
System.out.printf(" [%s : %s : %.15f] {%.15f, %.15f, %.15f}\n", dstr, d, d, bg1.doubleValue(), bg2.doubleValue(), bg3.doubleValue());
}
}
And this is the result:
1000000000000000.000000000000000
x [811.44 : 811.44 : 811.440000000000000] {811.440000000000000, 811.440000000000000, 811.440000000000055}
[811.44 : 811.44 : 811.440000000000000] {811.440000000000000, 811.440000000000000, 811.440000000000000}
x [425.53 : 425.53 : 425.530000000000000] {425.530000000000000, 425.530000000000000, 425.529999999999973}
[425.53 : 425.53 : 425.530000000000000] {425.530000000000000, 425.530000000000000, 425.530000000000000}
x [384.27 : 384.27 : 384.270000000000000] {384.270000000000000, 384.270000000000000, 384.269999999999982}
[384.27 : 384.27 : 384.270000000000000] {384.270000000000000, 384.270000000000000, 384.270000000000000}
From the output, it seems the lose of precision is introduced by the BigDecimal(double) constructor.

format decimal number to specific exponential format in java [duplicate]

I have this method:
public void Example(BigDecimal value, int scale){
BigDecimal x = new BigDecimal("0.00001");
System.out.println("result: " + (value.multiply(x)).setScale(scale, RoudingMode.HALF_UP).toString());
If, per example, value = 1 and scale = 2, the output is "result: 0.00". I thought it would be 1.00E-5. So, my doubt is: How can I force a BigDecimal to be formated in scientific notation if its scale is bigger than a certain value (it was 2 in my example) ?
Here is a version of DannyMo's answer that sets the scale automatically:
private static String format(BigDecimal x)
{
NumberFormat formatter = new DecimalFormat("0.0E0");
formatter.setRoundingMode(RoundingMode.HALF_UP);
formatter.setMinimumFractionDigits((x.scale() > 0) ? x.precision() : x.scale());
return formatter.format(x);
}
System.out.println(format(new BigDecimal("0.01"))); // 1.0E-2
System.out.println(format(new BigDecimal("0.001"))); // 1.0E-3
System.out.println(format(new BigDecimal("500"))); // 5E2
System.out.println(format(new BigDecimal("500.05"))); // 5.00050E2
You can use a DecimalFormat with setMinimumFractionDigits(int scale):
private static String format(BigDecimal x, int scale) {
NumberFormat formatter = new DecimalFormat("0.0E0");
formatter.setRoundingMode(RoundingMode.HALF_UP);
formatter.setMinimumFractionDigits(scale);
return formatter.format(x);
}
...
System.out.println(format(new BigDecimal("0.00001"), 2)); // 1.00E-5
System.out.println(format(new BigDecimal("0.00001"), 3)); // 1.000E-5
You could use something like this:
int maxScale = 2;
BigDecimal value = BigDecimal.ONE;
BigDecimal x = new BigDecimal("0.00001");
BigDecimal result = value.multiply(x);
if (result.scale() > maxScale) {
System.out.format("result: %.2E\n", result); // You can change .2 to the value you need
} else {
System.out.println("result: " + result.toPlainString());
}
Try the DecimalFormat class. It has format methods for methods for double and long numbers so you should do something like this:
BigDecimal x = new BigDecimal("0.00001");
DecimalFormat frmt = new DecimalFormat("0.00E00");
String formatted = frmt.format(x.doubleValue());
System.out.println("result: " + formatted);
DecimalFormat javadoc

Need assistance doing some specific formatting to an integer (java)

Alright im working on a radio program, and currently the radio frequencies are integers such as; 107900, 87900.
I need to convert numbers like that into strings that look like this,
107.9, 87.9
I've been playing around with DecimalFormat but haven't had any success. Any tips or hints are appreciated!
Here are some things i've tried,
frequency = 107900;
double newFreq = frequency / 1000;
String name = String.valueOf(newFreq);
result = 107.0
double freqer = 107900/1000;
DecimalFormat dec = new DecimalFormat("#.0");
result = 107.0
int frequency = 107900;
DecimalFormat dec = new DecimalFormat("#.0");
result = 107900.0
Thanks!
So as to not mess about with floating point, and assuming they're all one digit after the decimal (as radio stations are here, anyway), you can use:
String.format ("%d.%d", freq / 1000, (freq / 100) % 10)
See, for example, the following complete program:
public class Test {
static String radStat (int freq) {
return String.format ("%d.%d", freq / 1000, (freq / 100) % 10);
}
public static void main(String args[]) {
System.out.println("107900 -> " + radStat (107900));
System.out.println(" 87900 -> " + radStat ( 87900));
System.out.println("101700 -> " + radStat (101700));
}
}
which outputs:
107900 -> 107.9
87900 -> 87.9
101700 -> 101.7

what is the best way to handle double value while split?

String x = "39.33";
String result ;
Double x1 = new Double(x);
System.err.println("value :"+ x1);
String[] parts = x1.toString().split("\\.");
if(parts != null )
{
if((Integer.parseInt(parts[1])) > 0)
{
result =x1;
}
else
{
result= parts[0];
}
}
please let me know the best way to format/split the value:
my need is....
if x is 39
so x1 is 39.0
so i need result =39
if x is 39.33
so x1 is 39.33
so i need result =39.33
i dont want to use split or condition checking if((Integer.parseInt(parts[1])) > 0).. please let me know the best way for this?
Try this:
Double d = Double.parseDouble("35.0");
String result = NumberFormat.getNumberInstance().format(d.doubleValue())
System.out.println(result);
if you convert your double to an int the decimal places are ignored.
for this problem it would be something like that:
String result;
String x = "39.33";
Double x1 = new Double(x);
int xPre = x1.intValue();
if ( x1 > xPre) {
result = x1;
} else {
result = Integer.toString(xPre);
}
All you need to do is to read the number as a double and cast it to an int, which will effectively truncate the number.
You can do
String x = "39.33";
long l = (long) Double.parseDouble(x); // == 39
This will result in l being the whole number part of the double. (provided the number is less than 9 billion billion)
If you really want to use split you can do the following which will be slightly slower but will throw an exception if the number is too large.
long l = Long.parseLong(x.split("\\.")[0]);
public static void main(String[] args) {
Double x = new Double("39.33");
Double y = new Double("39.0");
printDouble(x);
printDouble(y);
}
public static void printDouble(Double dbl){
System.out.println(dbl.toString().replaceAll("[0]*$", "").replaceAll(".$", ""));
}

Math with bigdecimal resulting in 0

I'm trying to figure a problem out with BigDecimal. My code:
BigDecimal tweetcount = new BigDecimal(3344048);
BigDecimal emotionCountBig = new BigDecimal(855937);
BigDecimal emotionCountSentenceBig = new BigDecimal(84988);
MathContext mc = new MathContext(64);
PMI[cnt] = (emotionCountSentenceBig.divide((tweetcount.multiply(emotionCountBig,mc)),RoundingMode.HALF_UP));
What I'd like to do is: emotionCountSentenceBig/(emotionCountBig*tweetcount)
(The values can be bigger)
If i try this I get a zero, which is not possible. Any help ?
You need to specify the MathContext for the division too:
emotionCountSentenceBig.divide(tweetcount.multiply(emotionCountBig, mc), mc);
That gives the expected result:
2.969226352632111794036880818610913852084810652372969382467557947E-8
Now as rightly commented by #PeterLawrey you could use doubles instead:
public static void main(String[] args) throws Exception {
double tweetcount = 3344048;
double emotionCount = 855937;
double emotionCountSentence = 84988;
double result = emotionCountSentence / (tweetcount * emotionCount);
System.out.println("result = " + result);
}
which prints:
result = 2.9692263526321117E-8
Note that if you use:
double result = 84988 / (3344048 * 855937);
you are actually doing your operations (* and /) on integer and it will return 0. You can prevent it by explicitly using a double, for example (note the d):
double result = 84988d / (3344048d * 855937);
I would use double
int tweetcount = 3344048;
int emotionCountBig = 855937;
int emotionCountSentenceBig = 84988;
double pmi = emotionCountSentenceBig/((double) tweetcount * emotionCountBig);
System.out.println(pmi);
prints
2.9692263526321117E-8
which is close to the answer using BigDecimal
2.969226352632111794036880818610913852084810652372969382467557947E-8

Categories