Im using MPandroid chart to inflate Pie Chart, with some String JSON return
i tried to cast String value with float.parseFloat("3584907054456.48")
but it had exponent value when i log it, something like this 3584907E12
i need to get float value 3584907054456.48
is it possible ?
List<String> dataStackedSalesVolume1;
List<String> dataStackedSalesVolume2;
float[] firstDataStacked = new float[counte];
float[] secondDataStacked = new float[counte];
int counte = merchantECommerceDataAll.getData().getMerchantECommerceTipekartuList().getMerchantECommerceTipeKartuData().get(1).getDataSalesVolume().size();
dataStackedSalesVolume1 = merchantECommerceDataAll.getData().getMerchantECommerceTipekartuList().getMerchantECommerceTipeKartuData().get(0).getDataSalesVolume();
dataStackedSalesVolume2 = merchantECommerceDataAll.getData().getMerchantECommerceTipekartuList().getMerchantECommerceTipeKartuData().get(1).getDataSalesVolume();
for (int i=0; i< counte; i++) {
firstDataStacked[i] = Float.parseFloat(dataStackedSalesVolume1.get(i));
secondDataStacked[i] = Float.parseFloat(dataStackedSalesVolume2.get(i));
}
i tried to get the string and put it into new list and then parse that list and put parsed value into float[]
but it the results is rounded, i need to get the full length of data without rounded
Edit - The BigDecimal value can be converted to float value by using the floatValue() method. (Example - float requiredValue = bigDecimalValue.floatValue();)
Do note however that this will result in a drop in precision.
BigDecimal bigDecimalValue = new BigDecimal("3584907054456.48");
System.out.println(bigDecimalValue); //3584907054456.48
float floatValue = bigDecimalValue.floatValue();
System.out.println(floatValue); //3.58490702E12
//Formatted better to show the drop in precision.
System.out.println(String.format("%.2f", floatValue)); //3584907018240.00
Don't use float, use BigDecimal instead.
Do note that you won't be directly able to use operators such as +,-,*,etc. You'll have to use the provided methods, refer to the official documentation or an article such GeeksForGeeks articles to help you get an initial hang of it.
Sample code -
List<String> dataStackedSalesVolume1;
List<String> dataStackedSalesVolume2;
BigDecimal[] firstDataStacked = new BigDecimal[counte];
BigDecimal[] secondDataStacked = new BigDecimal[counte];
int counte = merchantECommerceDataAll.getData().getMerchantECommerceTipekartuList().getMerchantECommerceTipeKartuData().get(1).getDataSalesVolume().size();
dataStackedSalesVolume1 = merchantECommerceDataAll.getData().getMerchantECommerceTipekartuList().getMerchantECommerceTipeKartuData().get(0).getDataSalesVolume();
dataStackedSalesVolume2 = merchantECommerceDataAll.getData().getMerchantECommerceTipekartuList().getMerchantECommerceTipeKartuData().get(1).getDataSalesVolume();
for (int i=0; i< counte; i++) {
firstDataStacked[i] = new BigDecimal(dataStackedSalesVolume1.get(i));
secondDataStacked[i] = new BigDecimal(dataStackedSalesVolume2.get(i));
}
You can use something like BigDecimal.valueOf(new Double("3584907054456.48")) from java.math
After this you can divide, compare your value and so on
Related
I have two values and I am trying to compare them, but getting the worng results:
public void subtotal() throws Exception {
WebDriverWait wait = new WebDriverWait(session.driver, 100);
double subtotal_price = 0;
DecimalFormat decimal = new DecimalFormat("0.00");
WebElement subtotal = wait.until(ExpectedConditions.visibilityOf( element("Subtotal_cart")));
Float subtotal_value = Float.parseFloat(subtotal.getText().substring(1));
logger.info("subtotal_value"+subtotal_value);
File file = new File("ItemUPC/ItemUPC.txt");
Scanner sc = new Scanner(file);
while (sc.hasNextLine()) {
String[] line = sc.nextLine().split("[|]");
String price = line[2];
subtotal_price = subtotal_price + Double.parseDouble(price);
}
logger.info("subtotal_price"+subtotal_price);
if ((subtotal_value)==(subtotal_price))
{
logger.info("Subtotals updated");
}
else
{
logger.info("Subtotals not updated");
}
}
The following is the ItemUPC file:
2|BATH BENCH|19.00
203|ORANGE BELL|1.78
When I print the value of subtotal_price and Subtotal_value I am getting both as 20.78, but when its getting compared in the if statement, I am getting output as "Subtotals not updated"
Not sure where I am getting wrong. Can someone please help? Thank you.
Comparing floating point numbers can be challenging, due to differences in precision between floating point types and their binary representations of decimal numbers.
You have two simple options:
Compare the absolute value of the difference between the two values to an epsilon, or threshold, value
Use BigDecimal as a substitute for your Float and double variable types
Example 1:
// simplification that may fail in certain edge cases
static final double EPSILON = .001; // acceptable error - adjust to suit your needs
if (Math.abs(subtotal_price - subtotal_value) < EPSILON) {
logger.info("Subtotals updated");
}
// ...
Example 2:
BigDecimal subtotal_price = new BigDecimal("0");
// ...
BigDecimal subtotal_value = new BigDecimal(subtotal.getText().substring(1));
// ...
if(subtotal_price.compareTo(subtotal_value) == 0) {
logger.info("Subtotals updated");
}
// ...
I have some code like this:
void drawPlot()
{
String[] dataItemPrices = loadStrings("itemPrices.csv"); //load in .csv file, store as string array
itemName = new String[dataItemPrices.length-1];
itemPrice = new float[dataItemPrices.length-1];
for (int i=0; i<dataItemPrices.length-1; i++)
{
//split array to consider commas
String[] tokensItemPrices = dataItemPrices[i+1].split(",");
itemName[i] = tokensItemPrices[0];
itemPrice[i] = Float.parseFloat(tokensItemPrices[1]);
dataMin = min(dataMin,itemPrice[i]);
dataMax = max(dataMax,itemPrice[i]);
itemPriceScaled = new float[map(itemPrice[i], dataMin, dataMax,
0, (height-100))];
}
}
The last line of code is causing problems, when I compile I get "cannot convert from float to int".
The only int is the [i] but that's used to access an array, it can't be that can it? Otherwise how can I access the array?
Help please!
Thanks!
There are a few possible alternatives:
You are creating a new float array and you need an int size for it, does map return a float? If this is the case, map could need major modifications.
What kind of parameters does map need? itemPrice[i], dataMin and dataMax are all floats(height could be too), is this correct? In this case, a cast to (int) could be enough or your function prototype needs to be fixed...
Please add the code for map and all variables declarations to your question.
Edit:
After your comment and looking at your code, maybe this is what you want to do: populating an array with prices (taken from the itemPrice array) "scaled" using map that has obviously the same size as the other two arrays:
void drawPlot()
{
String[] dataItemPrices = loadStrings("itemPrices.csv"); //load in .csv file, store as string array
itemName = new String[dataItemPrices.length-1];
itemPrice = new float[dataItemPrices.length-1];
itemPriceScaled = new float[dataItemPrices.length-1]; // <<<<<Added
for (int i=0; i<dataItemPrices.length-1; i++)
{
//split array to consider commas
String[] tokensItemPrices = dataItemPrices[i+1].split(",");
itemName[i] = tokensItemPrices[0];
itemPrice[i] = Float.parseFloat(tokensItemPrices[1]);
dataMin = min(dataMin,itemPrice[i]);
dataMax = max(dataMax,itemPrice[i]);
itemPriceScaled[i] = map(itemPrice[i], dataMin, dataMax,
0, (height-100)); //<<<Modified
}
}
Complete newbie here guys. I'm working on a Java program to prompt the user for 3 variables which are used to calculate a future investment's value. Everything works perfectly, except when it comes time to put both my datatypes into ONE array.
Here's what the output SHOULD look like:
Year Future Value
1 $1093.80
2 $1196.41
3 $1308.65
...
This is what mine looks like:
Year 1
Future Value 1093.81
Year 2
Future Value 1196.41
Year 3
Future Value 1308.65
...
My year is an int value and my Future value is a double (rounded). I've been sitting here racking my brain and all the forums I can find and haven't been successful. Every time I put both value into an array I get an error about putting two different datatypes together. Any insight would be greatly appreciated. Below is the code for my full program:
import java.util.Scanner;
class investmentValue {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("Enter investment amount: $");
double i = s.nextDouble();
System.out.print("Enter percentage rate: ");
double r = s.nextDouble()/100;
System.out.print("Enter number of years: ");
int y = s.nextInt();
for (y=1; y<=30; y++) {
double f = futureInvestmentValue(i,r,y);
System.out.println("Year " + y);
System.out.println("Future Value " + f);
}
}
public static double futureInvestmentValue (double investmentAmount, double monthlyInterestRate, int years){
double value=1;
value = investmentAmount*Math.pow((1+(monthlyInterestRate/12)),(years * 12));
double roundValue = Math.round(value*100.0)/100.0;
return roundValue;
}
}
One solution is to start by implementing a pad function. Something like,
public static String pad(String in, int len) {
StringBuilder sb = new StringBuilder(len);
sb.append(in);
for (int i = in.length(); i < len; i++) {
sb.append(' ');
}
return sb.toString();
}
Now we can combine that with String.format() to get the dollars and cents, use a consistent printf() for the header and output lines. To get something like,
// Print the header.
System.out.printf("%s %s%n", pad("Year", 12), "Future Value");
for (int y = 1; y <= 30; y++) {
String year = pad(String.valueOf(y), 13); // <-- One more in your alignment.
String fv = String.format("$%.2f", futureInvestmentValue(i,r,y));
System.out.printf("%s %s%n", year, fv);
}
The System.out.println command isn't the only method available to you!
Try this in your loop:
System.out.print(y); // note that we use print() instead of println()
System.out.print('\t'); // tab character to format things nicely
System.out.println(f); // ok - now ready for println() so we move to the next line
Naturally, you'll want to do something similar to put your headings in.
PS - I'm pretty sure this is just an output formatting question - you don't really want to put all these values into a single array, right?
Given that you really are looking for formatted output, it may be better to use the printf() method.
The following inside the loop (instead of the 3 lines I wrote above) should do the trick (untested - I haven't used printf() format strings in a long, long time).
System.out.printf("%i\t$%0.2f", y, f);
EDIT: edited to answer your question in the comments about constructors... You should also check out this for further understanding
You could create a class that will hold both of the arrays...
This would give you a single object, let's call it StockData, that holds two arrays for the two separate types you need. You need to create the object once and then insert the data separately by type.
class StockData {
double[] data1;
int[] data2;
// default constructor
StockData() {
}
// constructor
StockData(double[] data1, int[] data2) {
this.data1 = data1;
this.data2 = data2;
}
// getters, setters...
}
Then you add data to an array of its type:
// using default constructor to add a single value to both arrays
StockData sd = new StockData();
sd.data1[INDEX_X] = YOUR_DOUBLE;
sd.data2[INDEX_X] = YOUR_INT;
// using default constructor to add all data to both arrays
StockData sd = new StockData();
sd.data1 = YOUR_ARRAY_OF_DOUBLE;
sd.data2 = YOUR_ARRAY_OF_INTS;
// using constructor to add all array data directly
StockData sd = new StockData(YOUR_ARRAY_OF_DOUBLE, YOUR_ARRAY_OF_INTS);
You could also have an object that will hold the double and int value, so the object will represent a single stock information of 2 values and then create an array containing those objects...
class StockData {
double data1;
int data2;
// default constructor same as before
// constructor
StockData(double data1, int data2) {
this.data1 = data1;
this.data2 = data2;
}
// getters, setters...
}
// ...
Adding data:
// create an array of StockData objects
StockData[] sd = new StockData[TOTAL_AMOUNT_OF_DATA];
// ... obtain your data
// using default constructor to add a single value to the array
sd[INDEX_X] = new StockData();
sd[INDEX_X].data1 = YOUR_DOUBLE;
sd[INDEX_X].data2 = YOUR_INT;
// using constructor to add all data directly
sd[INDEX_X] = new StockData(YOUR_DOUBLE, YOUR_INT);
If you want the program to have an specific format you could try to change your code and put this where your for is:
System.out.println("Year Future Value");
for (y=1; y<=30; y++) {
double f = futureInvestmentValue(i,r,y);
System.out.print(y);
System.out.println(" " + f);
}
this way you will have your output in the format you need without using arrays. But if you want to do an array for this you could declare an array of objects and create a new object with two attributes (year and future value)
Also your class name is investmentValue and it is recommended that all classes start with upper case it should be InvestmentValue
I hope that this can help you
A fun data structure you would be able to use here is a Map (more specifically in Java, a HashMap). What you are doing is associating one value with another, an integer to a double, so you could make something that looks like this:
Map<Integer, Double> myMap = new HashMap<>();
This would take the year as the integer, and the double as the price value, and you could iterate over the map to print each value.
Additionally if you really are looking for a "multidata type array," Java automatically casts from integer to double should you need to. For example:
int i = 2;
double[] arr = new double[2];
arr[0] = 3.14
arr[1] = i;
The above code is perfectly valid.
I'm trying to initialize my 2D array in java by passing specific double values into it, but I'm returning an error " ']' expected".
double[][] EnglishToFrenchProb = new double[2][3];
double[0][0] = 0.0; //unused
double[0][1] = 0.08;
double[0][2] = 0.06;
double[1][0] = 0; //unused
double[1][1] = 0.08;
double[1][2] = 0.06;
What am I doing wrong, and I realise there's an easier way to pass values into 2D arrays but this is the only way I could think where I can index them easily by their own values (which I need to do)
To set some value you have use variable's name:
EnglishToFrenchProb[0][0] = 0.00;
You can use also following syntax:
double[][] EnglishToFrenchProb = {{0.00, 0.08, 0.06}, {0.00, 0.08, 0.06}};
You need to refer to variable name:
double[][] EnglishToFrenchProb = new double[2][3];
EnglishToFrenchProb[0][0] = 0.0; //and so forth
I am trying to display numbers in a string dynamically, so if the number has decimal's display them but if not don"t show the .0
example: display 5.5 as 5.5 and 5.0 as 5
This is what I have so far: (answer is a double)
double temp = answer;
long temp2 = (long) temp;
if (temp == temp2) {
output = String.valueOf(temp2);
System.out.println(output);
this work's fine up to about 1e18 then will error out because of the maximum size of a Long.
So how would I achieve this on bigger numbers like 5.43e86
Use DecimalFormat
double answer = 5.0;
DecimalFormat df = new DecimalFormat("###.#");
System.out.println(df.format(answer));
The DecimalFormat suggestions are the easiest way to handle this. If they aren't sufficient, here's another idea.
If you're starting to hit the maximum values that can be represented by primitives in Java, then you may need to move to BigInteger and BigDecimal.
Try playing around with the BigDecimal.toBigInteger() method coupled with the toString() methods on BigDecimal and BigInteger.
It's not good solution
if you use new DecimalFormat("0.#") you are missing data, for example
PI = 3.14, but after parse you ae geting 3.1
Another solution to use eval%1 ? (int)d : d
this time couse max integer limit , again missing data
my solution is working, but it's not good idea
res = removeLastChars(eval,".0");
private String removeLastChars(double eval, String text){
String res = String.valueOf(eval);
int length = text.length();
if (res.length() > length){
res = res.substring((res.length() - length), res.length()).equals(text)
? res.substring(0, (res.length() - length)) : res;
}
return res;
}
Look at
http://download.oracle.com/javase/6/docs/api/java/text/DecimalFormat.html
you would want just DecimalFormat("0.0")