Possible loss of precision error Java - java

Quick question, I found answers close to this but nothing that helps me. I want it to print out a percentage at the end of the code that has 4 numbers after the decimal point, and of course, using an int work work. But using floats gives me an error.
This code:
import java.util.Scanner;
public class HW2johnson_pp4 {
public static void main(String args[]) {
Scanner keyboard = new Scanner(System.in);
System.out.printf("How many numbers will you enter?\n");
float[] numbers = new float[keyboard.nextFloat()];
System.out.printf("Enter " + numbers.length + " integers, one per line:\n");
for (int i = 0; i <= numbers.length - 1; i++) {
numbers[i] = keyboard.nextInt();
}
float sum = 0;
for (int i = 0; i <= numbers.length - 1; i++) {
sum += numbers[i];
}
System.out.printf("The sum is " + sum + "\n");
System.out.printf("The numbers are:\n");
for (int i = 0; i <= numbers.length - 1; i++) {
float perc = (numbers[i] / sum);
float perct = (perc * 100);
System.out.printf(numbers[i] + " which is " + perct + "%% of the sum.\n");
}
}
}
Gives the error:
HW2johnson_pp4.java:8: possible loss of precision
found : float
required: int
float[] numbers = new float[keyboard.nextFloat()];

You can't create an array of floats whose length is a floating-point value. That is to say, you can't have an array with 2.7 elements.
So the float within the length parameter is getting rounded, causing a loss of precision.
You wanted keyboard.nextInt() there on line 8, and keyboard.nextFloat() below on line 13.

You cannot initialize an array with floating point values.
float[] a = new float[4]
And not
float[] a = new float[4.0]
So, The problem is here:
float[] numbers = new float[keyboard.nextFloat()];
Use keyboard.nextInt() instead.

You're using keyboard.nextFloat(), which is a float, as the length of the array numbers. The length of an array has to be an int.

Thats because in line 8 you are making a new array, and passing a float as the length. Since all arrays require an integer as an array length, it will convert the float to an integer, and gives an error. You want to pass in an integer value.

Related

How to write a code to find the mode of the ints in the array without using a personally created method ie just regular "raw code"

I'm writing a code to find the mean, median and mode of an array of randomly generated ints (user inputs a size for the array and a range between which random numbers are to be generated it generate numbers between 3-22 randomly. I have not had too much trouble writing code for a mean or median but I cannot seem to be able to write code to calculate the mode (most commonly occurring number). Can anyone help or show/put code for how to calculate the mode of a randomly generated array of ints without having to create a method for yourself in the code? Thanks. Here is what I have so far (code that finds the mean and median):
public class ArraysIntsMeanMedianAndMode {
public static void main(String[] args) {
int ArraySize;
int min;
int max;
double x;
// To get the Size and range of numbers for the randomly genereated ints in the array.
Scanner sc = new Scanner(System.in);
System.out.println("What size should the array be?");
ArraySize = sc.nextInt();
System.out.println("Please enter a minimum value for the range of ints.");
min = sc.nextInt();
System.out.println("Please enter a maximum value for the range of ints.");
max = sc.nextInt();
//Making the array and filling it based on the user inputs
int[] MMMarray = new int[ArraySize];
int total = 0;
for (int i = 0; i < ArraySize; i++) {
x = (int) (Math.random() * ((max - min) + 1)) + min;
System.out.println(x);
int RandoNums = (int) x;
total = total + RandoNums;
MMMarray[i] = RandoNums;
}
//Finding mean/average
double Mean = (total + 0.0) / ArraySize;
System.out.println("The mean is: " + Mean);
//Finding Median/Middle number
Arrays.sort(MMMarray);
System.out.println(Arrays.toString(MMMarray));
if (ArraySize % 2 == 0) {
System.out.println("The median is: " + ((MMMarray[(ArraySize / 2)] + 0.0) + MMMarray[(ArraySize / 2) - 1]) / 2 + ".");
} else System.out.println("The median is: " + MMMarray[ArraySize / 2] + ".");
//How to find mode????????
Finding mode of unsorted array of int:
int freq = 0;
int value = 0;
int length = MMMArray.length;
for (int outer = 0; outer < length; outer++)
{
int tempFreq = 0;
for (int inner = 0; inner < length; inner++)
{
if (MMMArray[outer] == MMMArray[inner])
{
tempFreq++;
}
}
if (tempFreq > freq)
{
freq = tempFreq;
value = MMMArray[outer];
}
}
System.out.println("Mode is " + value + ", which appears " + freq + " times.");
Because you have already sorted the array to calculate the median, the problem of finding the mode(s) becomes equivalent to finding the longest consecutive streak of the same number. So, for example, if you have [1, 1, 2, 2, 2, 3, 5, 5, 21], there are three consecutive 2's, which is longer than any other run, so 2 is the mode.
To find the longest run, you can pass over the data once more, not reading any element twice. I'm adapting the code of Litvin and Litvin ever so slightly to use your array name, to count a run of 1 as a run, and to report what number the mode is rather than where it is in the array. You can drop this code in right where you ask your question, after the median has been calculated.
// at this point MMMArray is a sorted, nonempty array of int, because it was already sorted to find the median
int maxRunStart = 0, maxRunLength = 1;
int runStart = 0, runLength = 1;
for (int i = 1; i <= MMMArray.length; i++) //what they do here by using <=
//rather than < is worth reflecting upon
//it handles the case of the biggest run being at the end within the loop body
{
if (i < MMMArray.length && MMMArray[i] == MMMArray[i - 1])//notice how the boolean short-circuit prevents reading beyond the end of the array
{
runLength++;
}
else
{
if (runLength > maxRunLength)
{
maxRunStart = runStart;
maxRunLength = runLength;
}
runStart = i;
runLength = 1;
}
}
System.out.println("The mode is: " + MMMArray[maxRunStart] + ".");
}
Now here is something new to ponder. Suppose MMMArray contains [1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3]. This code (or that of MarsAtomic) will report 1 is the only mode. But the data is bimodal, and 3 is the mode as much as 1 is. One way to adapt the code would be to store the mode(s) in an array list (or an array, because we know up front there cannot be more modes than numbers). I think it is simpler (not more efficient, just easier not to mess up and without introducing another non-simple type) to make one more pass over the data. If you want that, then after the first for loop, instead of the println of the one mode, insert the following:
runLength = 1;
runStart = 0;
for (int i = 1; i <= MMMArray.length; i++)
{
if (i < MMMArray.length && MMMArray[i] == MMMArray[i - 1])
{
runLength++;
}
else
{
if (runLength == maxRunLength)
{
System.out.println("The mode is: " + MMMArray[runStart] + ".");
}
runStart = i;
runLength = 1;
}
}

How to calculate the percentage of even numbers in an array?

i am beginner and here is the method I am struggling with.
Write a method called percentEven that accepts an array of integers as a parameter and returns the percentage of even numbers in the array as a real number. For example, if the array stores the elements {6, 2, 9, 11, 3}, then your method should return 40.0. If the array contains no even elements or no elements at all, return 0.0.
here is what I have so far...
public static double percentEven(int[]a){
int count = 0;
double percent = 0.0;
if (a.length > 0){
for ( int i = 0; i < a.length; i++){
if ( a[i] % 2 == 0){
count++;
}
}
percent =(count/a.length)*100.0;
}
return percent;
}
i keep returning 0.0 when array contains a mix of even and odd elements but works fine for all even element array or all odd array? i can't see where the problem is?
thanks in advance.
count/a.length returns 0 since you are dividing two ints, and the second operand is larger than the first. Change it to (double)count/a.length in order to perform floating point division.
Alternately, change the order of operations to :
percent = 100.0*count/a.length;
For a simple division like 2*100.0/5 = 40.0, the above logic would work fine but think about the situation where we have 51*100.0/83 the output would be less readable and its always advisable to truncate the percentage to a limited decimal digits.
An example:
int count = 51;
Double percent = 0.0;
int length = 83;
percent = count*100.0/length;
System.out.println(percent);
output: 61.44578313253012
When you truncate it:
Double truncatedDouble = new BigDecimal(percent ).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue();
System.out.println(truncatedDouble);
output: 61.446
#Bathsheba : Well said, thanks for the suggestion.
Here is sample code :
public class PercentEven {
public static void main(String args[]){
int count = 0;
int[] a={2, 5, 9, 11, 0}; // this can be dynamic.I tried diff values
double percent = 0.0;
if (a.length > 0){
for ( int i = 0; i < a.length; i++){
if ( a[i] % 2 == 0){
count++;
}
}
percent = (100*count/a.length);
}
System.out.println(percent);
}
}
List<Integer> numbers = Arrays.asList(a);
int number = numbers.stream().filter(n->n%2==0).count();
int percent = number*100.0/numbers.size();
I have done this in java 8

Java Finding Average with Loop and Arrays

This is a Java problem I am having, I am somewhat new to Java.
I have to:
generate a random fraction
keep generating until the sum is greater than 1
then I have to display how many numbers I generated and which ones
Here is what I have so far in my function:
public static double calcAvg(int numOfTimes){
double sumOfRand = 0 ;
int numOffractions = 0;
double avg = 0;
double numOfAvg[] = new double[numOfTimes]; // number of rows
double randNums[] = new double[] {.1,.2,.3,.4,.5,.6,.7,.8,.9};
Random rand = new Random();
for(int i = 0; sumOfRand <= 1; i++){
int randNum = rand.nextInt(randNums.length); //gets a number from array randomly
//System.out.println(randNums[randNum]);
sumOfRand += randNums[randNum]; //adds it to the sum
numOffractions++; //counts # of avgnums needed for > 1
numOfAvg[i] = numOffractions;
}
avg = (numOfAvg[0] + numOfAvg[1] + numOfAvg[2]) /(numOfTimes);
return avg;
}
I keep getting an error on: numOfAvg[i] = numOffractions;
and I can't seem to add the fractions to the sum until they pass 1.
Well, your code is not related to your requirements..
You need something like this:
public static double calcAvg(){//What is the numOfTimes variable?!
double randNums[] = new double[] {.1,.2,.3,.4,.5,.6,.7,.8,.9}; //These can be define outside
Random rand = new Random();
List<Double> numbers = new LinkedList<Double>(); // This will have the list of numbers
double sum = 0;
while(sum<1){
int randNum = rand.nextInt(randNums.length);
numbers.add(randNums[randNum]);
sum+=randNums[randNum];
}
for(Double d:numbers){//Print the numbers
System.out.println(d);
}
System.out.println("Average: ", sum/numbers.size());
}
Hope you get array index out of bound when you call the function calcAvg with 1,2,3.
within the calAvg method you are using the numOfTimes as the array length and accessing numofAvg variable beyond the length range.
The logic needs to be revisited based on your requirement.

Finding standard deviation

I cant seem to figure out how exactly to find the standard deviation using what i have. the thing that is confusing me is really the whole standard deviation equation and how to exactly put it into code.
import java. util.Scanner;
public class StandardDeviation
{
public static void main (String[] args)
{
int array;
float sum = 0;
float mean;
Scanner scan = new Scanner(System.in);
System.out.println("Enter wanted array length:");
array = scan.nextInt();
float[] numbers = new float[array];
System.out.println("The size of the array: " + numbers.length);
for (int index = 0; index < numbers.length; index++)
{
System.out.print("Enter number " + (index+1) + ": ");
numbers[index] = scan.nextFloat();
}
for (float i : numbers)
{
sum += i;
}
mean = sum/numbers.length;
System.out.println("The mean is: " + mean);
}
}
You already have the mean, which is the first step in finding the standard deviation.
First, you loop through your array of numbers. You subtract the number from the mean, then square the answer. Add the squared answers together.
Next, divide your squared answer sum by the length of your array of numbers, minus 1.
Finally, take the square root of the result of the last step.
Sum (x - mean) * (x - mean)
Sum from step 1. / (length - 1)
Square root of the result from step 2.
Math.pow(number, 0.5D) gives you the square root of a double.

Adding and finding the average in an array

I"m trying to make a program that retrieves an endless amount of numbers that user inputs, and then it tells you how many numbers that you inputted, the sum of all the numbers, and then the average of the numbers. Here is the code I have so far. I don't know why it does not work. I get no errors, but it just does not get a valid sum or average.
import javax.swing.*;
public class SumAverage {
public static float sum;
public static float averageCalculator;
public static float average;
public static void main(String[]args) {
float numbers[] = null;
String userInput = JOptionPane.showInputDialog(null, "Ready to begin?");
if(userInput.equalsIgnoreCase("no"))
{
System.exit(0);
}
for(int i = 0; i != -2; i++)
{
numbers = new float[i + 1];
userInput = JOptionPane.showInputDialog(null, "Input any number. Input * to exit");
if(userInput.length() == 0 || userInput.equals("*") || userInput.equals(null))
{
break;
}
else
{
numbers[i] = Float.parseFloat(userInput);
}
}
for (int i = 0; i < numbers.length; i++)
{
sum += numbers[i];
}
average = sum / numbers.length;
JOptionPane.showMessageDialog(null, "The sum of all your numbers is " + sum + ". The average is " + average + ". You entered a total of " + numbers.length + " numbers.");
}
}
The problem is in this line:
numbers = new float[i + 1];
You are creating a new array, but you aren't copying the values from the previous array assigned to numbers into it.
You can fix this in two ways:
copy the values using System.arraycopy() (you'll need to use a new variable to make the call then assign it to numbers)
Don't use arrays! Use a List<Float> instead, which automatically grows in size
In general, arrays are to be avoided, especially for "application logic". Try to always use collections - they have many powerful and convenient methods.
If you wanted to store the numbers for later use, try making your code look like this:
List<Float> numbers = new ArrayList<Float>();
...
numbers.add(Float.parseFloat(userInput));
...
for (float n : numbers) {
sum += n;
}
average = sum / numbers.size(); // Note: Don't even need a count variable
And finally, if you don't need to store the numbers, just keep a running sum and count and avoid any kind of number storage.
Unrelated to the Q, but note also you can compute a running count/average without storing all the input data - or assuming you want to keep the input - without traversing over it each iteration. Pseudocode:
count = 0
sum = 0
while value = getUserInput():
count++
sum += value
print "average:" + (sum / count)
with
numbers = new float[i + 1];
you are creating a whole new array on every iteration. That means you are always creating a new array that will increase its size by 1 on each iteration but only having one field filled with the current user input and having all the other fields been empty.
Delete this line and initialize the array before.
If the size of the array should grow dynamically within the loop
do not use an array at all and use a dynamic data structure like a List or an ArrayList instead.
Further i would suggest to use
while (true) {
//...
}
to realize an infinite loop.

Categories

Resources