Converting from int to double in java - java

the following code calculates change dispensed by a vending machine. My problem? I cant get the change variable to work as the compiler wont let me due to two different data types (int & double conversion). Can anyone please help me solve this problem.
I have tried casting "change" but then it wont print right amount.
For example, if the change is 0.25 cents, change value remains zero..for obvious reasons of course. The problem begins at line 16. I have commented the part giving example as change = 0.25.
public String[] itemList = new String[] {"Water ","Coke ", "Diet Coke", "Iced Tea","Fanta "};
public double[] priceList = new double[] {75,120, 120, 100, 150};
public int[] itemQty = new int[]{10,10,10,10,10};
public int[] coinList = new int[]{100,50,20,10,5};
public int[] coinQty = new int[]{10,10,10,10,10};
public double change;
public double paid;
public void ReturnChange()
{
int Denominations=5;
int coins_dispensed = 0 ;
int[] InitialArray = new int[Denominations];
//My Problem begins here..for example if change is computed
change = 0.25; //change is a global declaration of type double and carries values derived from different function
int change1 = (int)change; //if i cast here, i get change as 0, thus the part that follows, fails to compute coins dispensed.
for (int i=0; i < 5; i++)
{
InitialArray[i] += coinQty[i]; // Copies Coin Quantity to Initial array for difference
}
System.out.println("Your change is "+NumberFormat.getCurrencyInstance().format(Math.abs(change1)) +" which comprises of:"); //OK till here
for (int i=0; i<5; i++)
{
if (coinQty[i]>0) //if a particular denomination is available
{
coins_dispensed = (change1/coinList[i]); //dividing coins dispense with denomination
coinQty[i] -= coins_dispensed; //reduce the quantity of the denomination dispensed
change1 = change1 - (coinList[i] * coins_dispensed); //total the change
}
else // Moves to next denomination if a particular coin runs out
{
coins_dispensed = (change1/coinList[i+1]);
coinQty[i+1] -= coins_dispensed ;
change1 = change1 - (coinList[i+1] * coins_dispensed);
}
}
if (change1 != 0) // In the case not enough coins to make change, selection is ignored.
{
System.out.println("\n\n\t Sorry. The machine doesnt have enough coins to make up your change. Your last transaction has been ignored.");
}
else
{
for (int i=0; i<Denominations; i++)
{
coins_dispensed = InitialArray[i] - coinQty[i];
System.out.println( "\n\t\t\t" + coins_dispensed +" of "+ coinList[i] + " cents coins");
}
}
}

You should use use integers everywhere but count in cents not dollars. Just divide your numbers by 100 when you print them.
This is because floats and doubles cannot accurately represent the base 10 multiples used for money and will introduce rounding errors, particularly when multiplying to calculate interest rates for example.
See Why not use Double or Float to represent currency? for more information and discussion.

It seems all your variables hold prices in cents (i guess a coke is not 120 $). But your change is apparently specified in dollars. So what you could do is multiply change by 100 and then cast it to int.
Like that:
int change1 = (int) (change * 100); // convert dollars to cents and cast to int
If you need to output change1 in dollars (and not cents) at some point, you have to convert it back:
float result = change1 / 100.0f;

Related

Using info from two arrays to calculate contents of third array

I have an array with the total population of a country and another array with the total number of cases of COVID for each country. I need to divide the number of cases by the total population and store the percentage in a third array. I'm stuck on the syntax though and no one from my class is available for outreach until tomorrow. Can anyone please help me get past this step? I've tried lots of different ways of getting the new percentage array, but nothing works. I can't use int for the percentage because my professor wants it with four places after the decimal. No references in the examples or the book match what I'm trying to do.
Thanks in advance for your advice!
int[] cases = {10_036_282, 8_553_657, 5_675_032, 1_856_292, 1_781_997, 1_381_218, 1_250_499, 1_216_747, 1_149_068, 967_825};
int[] population = {327_096_265, 1_352_647_786, 209_469_323, 64_990_511, 145_734_038, 46_692_858, 44_361_150, 67_141_684, 49_661_048, 126_190_788};
//You must calculate the percentage of cases based on the number of cases and the population.
for (int i = 0; i < countries.length; i++){
double percentage[i] = ((cases[i] / population[i]) * 100);
}
Unless otherwise explicitly instructed, you should use doubles for percentages. Otherwise, cases[i] / population[i] is going to normally result in 0
double[] percentage = new double[...];
percentage[i] = ((cases[i] / (double)population[i]) * 100);
For simplification calculate everything just put into double and than convert the calculated value to int and store in the array.
Here you go!
import java.util.Queue;
import java.util.LinkedList;
import java.util.Arrays;
class Main{
public static void main (String[] args) {
int[] cases = {10_036_282, 8_553_657, 5_675_032};
int[] population = {327_096_265, 1_352_647_786, 209_469_323};
int[] percentage = new int[cases.length];
for(int i = 0; i < cases.length; i++){
double temp = ((double)cases[i] / (double)population[i] ) * 100;
int pr = (int) temp;
percentage[i] = pr;
}
System.out.println(Arrays.toString(percentage));
}
}
all of your number is in integer and division of integer by integer is an integer, at first you need to cast one or all of the values to double, and secondly you said with 4 decimal points so you need to format your decimal number as below:
int[] cases = { 10_036_282, 8_553_657, 5_675_032, 1_856_292, 1_781_997, 1_381_218, 1_250_499, 1_216_747,
1_149_068, 967_825 };
int[] population = { 327_096_265, 1_352_647_786, 209_469_323, 64_990_511, 145_734_038, 46_692_858, 44_361_150,
67_141_684, 49_661_048, 126_190_788 };
double[] average = new double[cases.length];
for (int i = 0; i < average.length; i++) {
average[i] = ((cases[i] / (double)population[i]) * 100.0);
average[i] = Double.parseDouble(String.format("%.4f", average[i]));
}

The question is around the "Gambling" zone with addition of math

after adding two int variables to (a) and (b),
I have to gamble (a) times values between 10 to 100 and
calculate which square root of these gambled numbers is the closest to (b).
For example a=3 and b=2
output:
Gambled 16,25,49.
The number 16 was chosen since it's square root (4) is the closest to b=2.
I am stuck in the part of calculation of the square root, and saving the closest value to b each time the loop runs, i'm not allowed to use arrays,
this is the third question of my first task and i'd appreciate any experienced ideas to be shared ^^.
(MyConsole is a replacement for the scan command)
int a = MyConsole.readInt("Enter value a:");
int b = MyConsole.readInt("Enter value b:");
for(int i = 0; i<a; a--){
int gambler = ((int)(Math.random() *91)+10);
double Root = Math.sqrt(gambler);
double Distance= Root-b;
{
System.out.println();
Here is how I found the minimum. You can also use arrays to store all the gambling values if you want for future use. I also used Scanner but you can use your MyConsole I'm just not familiar with it. I hope it helps. דש מישראל
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter value a:");
int a = scanner.nextInt();
System.out.println("Enter value b:");
int b = scanner.nextInt();
double min = 100;
for (int i = 0; i < a; i++) {
int gambler = ((int) (Math.random() * 91) + 10);
double root = Math.sqrt(gambler);
double distance = Math.abs(root - b);
if (min > distance)
min = distance;
}
System.out.println("minimum value is: " + min);
}

Statistical method

So in my code, it seems that in the fillRandomArray method, instead of getting an array of 100 random numbers, I just get straight zeros and I don't know how to fix it. It seems to me that the problem has to do with the first for loop, or potentially the declaration of the double array in the public class statistical model.
import javax.swing.*;
import java.util.*;
import java.util.Arrays;
public class statisticalModel {
//Initates a place for the normal curve to be placed.
static double Ho;
//Real proportion of data statistic.
static double Ha;
//Estimated real proportion of data statistic.
static int Pop;
//Population size.
static int Zscore;
//Z score, or the amount of standard deviations away from the mean.
//Z score = sqrt(P(1-p)/N)
static double stdDev;
//Standard Deviation, follows the 65, 95, 99 model. 65 percent of all scores
//fall in one standard deviation of the mean. 95 percent of all scores fall
//within two standard deviations of the mean. 99 percent of all scores fall
//within three standard deviations of the mean.
static double mean;
//The average of all the scores of the array.
static double variance;
//The average difference between sets of values within the array.
static double[] meanScores = new double[100];
//Array meant to generate a set of random values within the normal curve of
//the model, following the 65, 95, 99 rule.
static String desiredValue = "";
//This is a string set to the user's command. Tells whether or not the value should
//be lower than, higher than, or not equal to Ho.
static Scanner sc = new Scanner(System.in);
//Scanner to take in values listed above.
static int size = 100;
//Variable that measures the size of the array.
static int temporary;
//Value Holder for For Loops, While Loops, If Statements, etc.
static double pValue;
//P Value which represents how far a statistic deviates from the expected mean of a population.
public static void main(String args[])
{
runStatisticalMethod();
}
public static void runStatisticalMethod()
{
takeInData();
calculateStats();
System.out.println(Arrays.toString(meanScores));
explainSolution();
}
public static void takeInData()
{
System.out.println("Please enter your desired Ho");
Ho = sc.nextDouble();
System.out.println("Please enter your desired Ha");
Ha = sc.nextDouble();
System.out.println("Please enter your desired population size");
Pop = sc.nextInt();
System.out.println("Thanks for entering your data. Your data will be compiled below");
}
//Fills the array meanScores with random integers.
public static void fillRandomArray()
{
for (int z = 0; z < 100; z++) {
meanScores[z] = (Math.random() * 100) + (stdDev * 3);
}
assignStdDev();
for (int x = 0; x < 99; x++) {
for (int y = 0; y < 99; y++) {
if (meanScores[y] >= meanScores[y + 1]) {
double valueHolder1 = meanScores[y];
double valueHolder2 = meanScores[y + 1];
meanScores[y + 1] = valueHolder1;
meanScores[y] = valueHolder2;
}
}
}
}
public static void assignStdDev()
{
for (int x = 5; x >= 5 && x <= 95; x++) {
meanScores[x] -= (stdDev * Math.random());
}
for (int x = 31; x >= 31 && x < 66; x++) {
meanScores[x] -= (stdDev * Math.random());
}
}
//Calculates a set of statistics including standard deviation, z-score, mean,
//interquartile range, probability, and variance.
public static void calculateStats()
{
//Calculates the Mean of the inputted variables and normal curve.
int sum = 0;
for (int a = 0; a < 100; a++) {
sum += a;
}
mean = sum / size;
//Calculate the Variance of the inputted variables and normal curve.
for (int b = 0; b < 100; b++) {
temporary += (b - mean) * (b - mean);
}
variance = temporary / size;
//Calculate the Standard Deviation of the inputted variables and normal curve.
stdDev = Math.sqrt(variance);
//Calculate the P-Value and use the p value to determine whether or not the hypothesis is valid.
pValue = (Ha - Ho) / (stdDev / Math.sqrt(Pop));
}
//This method explains the numbers generated in terms of statistics and analyzes
//if the hypothesis is probably. If not, a possible solution is proposed with
//regards to what should be changed. Also explains the curve of the graph.
public static void explainSolution()
{
if (Math.abs(pValue) < .05) {
System.out.println(
"Based on the information you have given me, the hypothesis test seems to show information that your Ha is possibly correct, thus failing to reject your hypothesis");
} else if (Math.abs(pValue) > .05) {
System.out.println(
"Based on the information you have given me, the hypothesis test seems to lack information to show that your Ha is possibly correct, thus rejecting your hypothesis");
}
}
}

Function giving incorrect result

I know something is wrong with my variables storing the info.
At the end of the program, it prints 0.0 for rate.
I have been trying to figure out the error in logic or syntax in my program. I believe it may have something to do with the variables being 0, I have also tried inserting the function into the loop when count == floor.
import javax.swing.*;
public class pickanumber {
public static void main(String[] args) {
int floor=1, rooms, occupants, rsum = 0, osum = 0;
String amount;
do {
amount = JOptionPane.showInputDialog("Enter total floors.");
floor = Integer.parseInt(amount);
} while (floor <= 0);
for (int count = 1; count <= floor; count++) {
if (floor==13) count++;
do {
amount = JOptionPane.showInputDialog("Enter total rooms on floor "+count+".");
rooms = Integer.parseInt(amount);
} while(rooms <= 9);
rsum += rooms;
do {
amount = JOptionPane.showInputDialog("Enter occupants on floor "+count+".");
occupants = Integer.parseInt(amount);
} while ((occupants > rooms)||(occupants < 0));
osum += occupants;
}
int rate = (osum/rsum)*100;
JOptionPane.showInputDialog("occupancy is at "+rate+"% capacity.");
}
}
osumand rsum are both integers, they represent numbers without decimal.
Any math opertion using only those 2 integers will return an integer.
So osum/rsum will return
0 if osum < rsum
1 if rsum <= osum < 2*rsum
etc.
If you want to get the decimal value of this division, you can
define your rate as double type in order to contain decimal numbers.
cast at least one of your varaible as a double in the operation
You should end with something like:
double rate = (((double) osum)/rsum)*100;
The problem lies within the datatypes i guess (or atleast i couldn't think of anything else). the result of (osum/rsum) must be integer, and will therefor nearly always be 0 (or 1, if osum == rsum). Simply cast them to double before the division, and cast the result of the complete calculation back to integer, and things should work quite fine.
Double drsum = (double) rsum;
Double dosum = (double) osum;
Double rate = (dosum/drsum)*100;
int i = rate.intValue();

Rounding Off to 2 decimal places giving issues while summing up

Getting the following sets of numbers -->
[5.1429,5.1429,5.1429,5.1429,5.1429,5.1429,5.1426]
[0.8333,0.8333,0.8333,0.8333,0.8333,0.8335]
When added, these give a whole number.
Now we have to display these numbers after rounding to 2 decimal places which look like this -->
[5.14, 5.14, 5.14, 5.14, 5.14, 5.14, 5.14]
[0.83, 0.83, 0.83, 0.833, 0.83, 0.83]
Which is not summing up to a whole number. This is causing the whole total to come something like 99.96 or 101.01.
Is there a way we can round the numbers so that the total comes to a whole number.
I am not looking for a way to round off the sum. i am looking for a way to manipulate the already rounded numbers (like 5.14,5.14.. etc) so that they give a whole number. (if there is a way.. that is :) )
You would introduce the smallest absolute rounding error - while keeping the total sum intact - if you sort the inputs by decreasing third decimal and round everything down, except for just enough numbers to reach the target.
As a simple example:
input
0.132, 0.226, 0.257, 0.385 // sums up to 1.00
sort by 3rd decimal (descending)
0.257, 0.226, 0.385, 0.132
round everything down
0.25, 0.22, 0.38, 0.13 // sums up to 0.98
round up just enough to reach a whole number
0.26, 0.23, 0.38, 0.13 // sums up to 1.00
In code (untested):
public void printRounded(double[] ds) {
// create wrapper objects
int n = ds.length;
Wrapper[] ws = new Wrapper[n];
for (int i = 0; i < n; i++)
ws[i] = new Wrapper(i, (int)(ds[i] * 1000) % 10, (int)(ds[i] * 100));
// sort by third decimal, descending
Arrays.sort(ws, new Comparator<Wrapper>() {
public int compare(Wrapper o1, Wrapper o2) {
return o2.thirdDecimal.compareTo(o1.thirdDecimal);
}
});
// find number of elements that must be rounded up and increment
int sum = 0;
for (int i = 0; i < n; i++)
sum += ws[i].prefix;
int numberToIncrement = 100 - (sum % 100);
for (int i = 0; i < numberToIncrement ; i++)
ws[i].prefix++;
// sort back to input order
Arrays.sort(ws, new Comparator<Wrapper>() {
public int compare(Wrapper o1, Wrapper o2) {
return o1.index.compareTo(o2.index);
}
});
// print values
for (int i = 0; i < n; i++) {
System.out.println(ws[i].prefix / 100 + "." ws[i].prefix % 100);
}
}
private class Wrapper {
public Wrapper(int index, int thirdDecimal, int prefix) {
this.index = index;
this.thirdDecimal = thirdDecimal;
this.prefix = prefix;
}
public int index;
public int thirdDecimal;
public int prefix;
}
Instead of using the custom formatting you could of course convert the ints back to double and use standard formatting.
If I round the result, I get a whole number.
public static void main(String... ignored) {
sum(5.1429, 5.1429, 5.1429, 5.1429, 5.1429, 5.1429, 5.1426);
sum(0.8333, 0.8333, 0.8333, 0.8333, 0.8333, 0.8335);
}
private static void sum(double... xs) {
double sum = 0;
for (double x : xs) {
sum += x;
}
System.out.printf("sum was %.2f%n", sum);
}
BTW: If you know you expect a whole number, you should round to a whole number, not two decimal places.
There's no way to do this unless you abandon the firm requirement
for rounding your numbers (to 2 decimal places) and allow for
(a) truncating your numbers (after the 2nd decimal place);
(b) rounding up/down when actually you need to round down/up.
If you allow for these operations (on some of the numbers) instead of
rounding all of them by the book, then most probably you can come up
with some algorithm which would give you the same (integral) sum even
after the rounding/truncation operations is applied on the original
numbers. But again, this is not really rounding (as we know it from math).
One way you could do it would be to round to two decimal places then take each number an multiply it by a hundred and divide it by the sum of the numbers. This should get you closer to 100 and if you iterate over that enough times your result should approach 100. So basically (pseudcode)
lsum = 0
vecNums = //previous numbers
while abs(nsum -100) >.01
for i in vecNums
i = (i*100)/sum(vecNums)
return vecNums
You could just sum them up as you did, and then round the final sum as well.
You can take a look at the Math.round(double a) method
System.out.println(Math.round(12.51));//Yields 13
System.out.println(Math.round(12.49));//Yields 12
System.out.println(Math.round(12.50));//Yields 13
from Round off in JAVA

Categories

Resources