How to use double for matrices - java

This is the code I wrote:
public class main
{
public static int arraySum(int[] arr)
{
int result = 0;
for(int i = 0; i < arr.length; i++)
{
result += arr[i];
}
return result;
}
public static int arraySumBetter(int[] a)
{
int result = 0;
for(int value : a)
{
result += value;
}
return result;
}
public static void main(String[] args)
{
int[] a = {1, 2, 3, 4, 48};
System.out.println(arraySum(a));
System.out.println(arraySumBetter(a));
}
}
When I run it, it prints:
58
58
But I want the result to be 58.0.
I changed all the int into double:
public class main
{
public static double arraySum(double[] arr)
{
double result = 0;
for(double i = 0; i < arr.length; i += 1)
{
result += arr[i];
}
return result;
}
public static int arraySumBetter(double[] a)
{
double result = 0;
for(double value : a)
{
result += value;
}
return result;
}
public static void main(String[] args)
{
double[] a = {1, 2, 3, 4, 48};
System.out.println(arraySum(a));
System.out.println(arraySumBetter(a));
}
}
But it didn't compile:
typed.java:8: error: incompatible types: possible lossy conversion from double to int
result += arr[i];
^
typed.java:19: error: incompatible types: possible lossy conversion from double to int
return result;
^
2 errors
Do I need to add more code? Or something else?

This is a slightly sneaky one: look at this code
for (double i = 0; i < arr.length; i += 1) {
result += arr[i];
}
the variable used for index of the array is a double all of a sudden, but an array index is always an integral value. That's what causes the compilation error.
Revert the index variable to int and you'll be all set. That is, revert your code to
for (int i = 0; i < arr.length; i += 1) {
result += arr[i];
}
Note: if all you want is just a result with one decimal, the solution you choose is pretty heavy handed, calculations on doubles are slower than those on integers, and double math has its own challenges - just look around here on SO. A simple way to keep all calculations in ints but at the same time print the result with 1 decimal could be
System.out.format("%.1f", (double) arraySumBetter(a));
in that case, you'd use the first version of arraySumBetter, ie public static int arraySumBetter(int [] a)

The problem is that an array can only be indexed using integers. This means, arr[true] or arr[5.32] is not allowed.
The compiler complains because it needs to convert the double to an integer value, and this would cut off the decimal places. Java never does that implicity - you have to cast it to an integer:
double foo = 5.32;
// convert to integer:
int bar = (int) foo;
In your case a typecast is not necessary. If the variable i is of type int, it works fine.
In the second method, you have the wrong return type. It returns a double, but the declaration says
public static int arraySumBetter

your problem in this function int arraySumBetter(double [] a)
return value is int but you declared result in your function as double variable so it will be a lossy conversion from double to int problem when you return result
it should be:
public static double arraySumBetter(double [] a)
also index counter type of array should be integer value :
for (int i = 0; i < arr.length; i += 1) // not double i
you can format your output in specific floating point precision using printf method:
System.out.printf("%.1f\n",arraySum(a));
System.out.printf("%.1f\n",arraySumBetter(a));

Related

Random array with size, min and max value with short

I'm doing a task where you input 3 parameters which are size, minimum value and maximum value. It then is meant to return a random number between the minimum and maximum value of the size inputted. There are also other validations such as if the min is more than the max which I've already done.
I am able to do the task using integer instead of short. As soon as I change the data type a bunch of errors come.
Below is what I've done so far, it works as expected but I am pretty sure that there is not meant to be a bottom return null, I get errors when I delete it. On the second loop, it should return the array instead of doing a system print line. The other issue is the data types at the top, it should be short maxVal and short minVal instead of int but I can't get it to work with short.
I would very much appreciate all help. Thanks!
public static ArrayList<Short> RandomArray1(int n, int maxVal, int minVal){
if(n <= 0) {
return null;
}
if(minVal > maxVal) {
return new ArrayList<Short>();
}
ArrayList<Integer> ran = new ArrayList<Integer>();
Random rand = new Random();
for(int i = 0; i < n; i++) {
int result = rand.nextInt(maxVal-minVal) + minVal;
//System.out.println(result);
ran.add(result);
}
for (int i = 0; i < ran.size(); i++) {
System.out.println(ran.get(i));
//return (ArrayList<Short>)ran.get(i);
}
return null;
I would do it like this.
first, method names by convention should start with lower case letters.
Use the method to generate the values and return the list
return interface types as opposed to implementation types (e.g. List)
throw exceptions if the arguments don't satisfy the requirements.
Note, having to cast the arguments to shorts is cumbersome but it prevents errors at compile time. Otherwise you may want to throw an additional run time exception if the values aren't within Short.MIN_VALUE and Short.MAX_VALUE.
public class RandomShorts {
public static void main(String[] args) {
List<Short> shortList = randomList(20, (short)200, (short)99);
shortList.forEach(System.out::println);
}
public static List<Short> randomList(short n, short maxVal,
short minVal) {
if (n <= 0 || minVal >= maxVal) {
throw new IllegalArgumentException(
"\nn must be > 0\nminVal must be < maxVal\n");
}
List<Short> ran = new ArrayList<>();
Random rand = new Random();
for (int i = 0; i < n; i++) {
short result =
(short) (rand.nextInt(maxVal - minVal) + minVal);
ran.add(result);
}
return ran;
}
}
If you just want to return a single random number using the supplied arguments, they you can do it like this.
public static short randomShort(int n, short maxVal, short minVal) {
return (short)((Math.random()*(maxVal - minVal))+minVal);
}
For adding the short to random list since there is not Random.nextShort(), you'll have to substitute the line
int result = rand.nextInt(maxVal-minVal) + minVal;
for
short result = (short) (rand.nextInt(maxVal-minVal) + minVal);
Where then you can add to your ran array instead of the second for loop returning the ArrayList as a short
public static short[] generateRandomShortArray (int sampleSize, short min, short max) {
short[] result = new short[sampleSize];
for (int index = 0; index < result.length; index++) {
result[index] = (short)((Math.random() * (max-min)) + min);
}
return result;
}
If an array list is required just return Arrays.asList(result);

Is there a prevalent technique to sum the elements of an array having generic type but limited to Number?

I created a generic-type array bounded with Number. I created a method to sum all of its elements.
Here is the code
class GenericMethod {
public static void main(String[] args) {
Integer[] arr = {10, 20, 30, 40, 50};
int sum = GenericMethod.<Integer>sumOfAllElements(arr);
System.out.println(sum);
Float[] floats = {3.0f, 4.19f};
int sum2 = GenericMethod.<Float>sum(floats);
System.out.println(sum2);
}
public static <T extends Number> int sumOfAllElements(T[] arr) {
int response = 0;
for (T t : arr) {
response += t.intValue();
}
return response;
}
}
In the method, the return type is still an int. I would like to change the return-type to a generic as well.
I've tried declaring the response variable with the generic-type N but then I can't initialize it with 0 or even with the Integer wrapper class'
N result = Integer.valueOf(0);
which I initially thought might be possible since the Integer class extended the Number class.
Then I tried initializing it as null
N result = null;
but then this line,
result = result + array[i].intValue();
throws an error stating Operator + cannot be applied to N, int. I can't change the line to
result = result + array[i];
because then it shows Operator + cannot be applied to N, N.
I've also tried this "hack"
public static <N extends Number> N sum(N[] array) {
Number result = array[0];
if (result instanceof Integer) {
Integer temp = result.intValue();
for (int i = 0; i < array.length; i++) {
temp += array[i].intValue();
}
result = temp;
}
return (N) result;
}
but then I would have to specify the cases for all Number types.
Could someone please help me with,
- modifying this method, so that it could return a generic-type instead of int.
- help me understand the nature and cause of this problem, is it because the class is still a non-generic type?
The simplest method, if using Java 8+, would be to use Arrays.stream(T[]) to create a stream of T(s) and then reduce that stream with addition. Like,
Integer[] arr = { 10, 20, 30, 40, 50 };
Float[] floats = { 3.0f, 4.19f };
System.out.println(Arrays.stream(arr).reduce((a, b) -> a + b));
System.out.println(Arrays.stream(floats).reduce((a, b) -> a + b));
No additional methods required. But, if you want to make that a method, you could pass the operation like
public static <T> T add(T[] arr, BinaryOperator<T> op) {
return Arrays.stream(arr).reduce(op).get();
}
and then call it like
System.out.println(add(arr, (a, b) -> a + b));

How to use loops to find the exponent of a base that produces an argument

I am attempting to use loops to find the exponent of a given base that produces a specific argument. For example, in the equation 5^x=625, 5 would be the base and 625 would be the argument. I know that in that equation x=4 but I am unsure of how to get 4 in my return.
Here is what I have so far:
public static int log(int base, int argument) {
int result = 1;
for (int i=0; i<=; i++)
result = ;
return result;
}
I am unsure what to put for my condition statement and my result. What am I missing here?
edit: I forgot to mention that I am attempting to do this without using the math library. I also thought it might help to include my code for finding the powers:
public static int pow(int base, int exponent) {
int result = 1;
for(int i=0; i<exponent; i++) {
result = result*base;
}
return result;
I essentially just trying to reverse this to find the exponent.
Something like that:
public static int log(int base, int argument) {
if(argument <= 0 || base <= 0) {
throw new IllegalArgumentException("This method only works with positive integers");
}
int result = 1;
int i = 0;
while(result < argument) {
result = result * base;
i++;
}
if(result == argument) {
return i;
} else {
throw new IllegalArgumentException("There is no integer for x in base^x = argument");
}
}
This as some flaws as it handle all cases but it's a start.
This is more of a math question.
For the formula 5^x = 625, you find x using x = logâ‚…(625) = log(625)/log(5).
So:
public static int log(int base, int argument) {
return (int) (Math.log(argument) / Math.log(base));
}
But maybe you already knew this, since you named the method right.
Count how many times you can divide the argument by the base while the result is 1 or greater:
public static int log(int base, int argument) {
int result;
for (result=0; argument>=1 ; result++) {
argument = argument/base;
}
return result;
}

Java: Adding Digits Of A String

I have the correct code, I found an answer long ago, however I still don't understand why it works.
class Main {
public static void main(String[] args) {
System.out.println(D5PSum(10));
}
private static int D5PSum(int number) {
String n = Integer.toString(number);
int sum = 0;
for (int i = 0; i < n.length(); i++) {
// (1) WHY DOES THIS NOT WORK
//sum += Integer.parseInt(number.charAt(i));
// (2) MORE IMPORTANTLY WHY DOES THIS WORK
char c = n.charAt(i);
sum += (c-'0');
// (3) WHAT IN THE WORLD IS c-'0'
}
return sum;
}
}
// (1) WHY DOES THIS NOT WORK
because Integer.parseInt(...); is expecting a string as parameter not a char
// (2) MORE IMPORTANTLY WHY DOES THIS WORK
char c = n.charAt(i);
any char is nothing else as an integer mapped to a table of symbols...(ASCII table for example) so this (c - '0') is just another valid mathematical operation
charAt is not a valid method of the primitive type int.
'0' is the character 0, and the character encoding set that Java uses has 0 to 9 in a consecutive block. Therefore c - '0' yields the position of c in that consecutive block which is therefore the value of the digit. (Actually this sort of thing is idiomatic C - goes right back to the 1960s).
You should first convert String to Int.. Please check the below code:
class MainClass {
public static void main(String[] args) {
System.out.println(D5PSum(11));
}
private static int D5PSum(int number) {
String n = Integer.toString(number);
System.out.println(n);
int sum = 0;
for (int i = 0; i < n.length(); i++) {
// (1) WHY DOES THIS NOT WORK
String str = String.valueOf(n.charAt(i));
sum += Integer.parseInt(str);
// (2) MORE IMPORTANTLY WHY DOES THIS WORK
// char c = n.charAt(i);
// sum += (c-'0');
// (3) WHAT IN THE WORLD IS c-'0'
}
return sum;
}
}
1
It doesnt work because Integer.parseInt takes a String and String.charAt returns a char(actar). Integer.parseInt (Character.toString(n.charAt(i))) would Work.
2/3
A char represents a number between 0 and 65535. EACH digit-characters (0-9) has a number in that range which depends on the charset. All digits are typically in a row, for example the character 0 has the value 48, 1 49 and 9 57. So ich you want to know the digit value of a char you simply subtract the character value of 0 from your character. That is the Line c-'0'
// (1) WHY DOES THIS NOT WORK
//sum += Integer.parseInt(number.charAt(i));
number is a variable of primitive data type "int" so number.charAt(i) won't work.
// (2) MORE IMPORTANTLY WHY DOES THIS WORK
char c = n.charAt(i);
n is an instance of String and we are getting the character at i th position in the n string
sum += (c-'0');
// (3) WHAT IN THE WORLD IS c-'0'
for every character there is an ascii code assigned. '0' = 48, 'c' = 99. That's the reason why it works here. when 'c'-'0' is executed, it's equivalent to 99-48
Why convert to a string in the first place? The simplest and fastest way to solve this is without deviation to strings:
private static int D5PSum(int number) {
int v = number, sum = 0;
while (v != 0) {
sum += v % 10;
v /= 10;
}
return sum;
}
If you want your code (the part which does not works to work then do this).
class Main {
public static void main(String[] args) {
System.out.println(D5PSum(10));
}
private static int D5PSum(int number) {
String n = Integer.toString(number);
int sum = 0;
for (int i = 0; i < n.length(); i++) {
sum += Integer.parseInt(n.charAt(i)+"");
}
return sum;
}
}
To get sum of the digits of a string str:
int sum = str.chars().map(Character::getNumericValue).sum();

Incorrect return on binary to dec converter

Fixing up and tidying the converter when I noticed that it somehow gives out incorrect conversions.
For example, when creating a new number to convert using BinaryNumber bn1 = new BinaryNumber("1011"); and then asking it to give out a result with System.out.println(bn1.convertToDecimal()); it prints out 3 instead of the correct result of 11.
I'm almost sure I got the actual conversion wrong but going through it in my head I can't find the mistake.
public class BinaryNumber {
private String n;
public BinaryNumber(String pn) {
n = pn;
}
public String getN() {
return n;
}
// Creating the .convertToDecimal()
public int convertToDecimal() {
int bitPosition = 0;
int sum = 0;
for (int i = n.length() - 1; i >= 0; i--) {
sum = sum + (int) Math.pow(2, bitPosition) * (n.charAt(i) - 48);
}
return sum;
}
// Creating the .add to add the two different binary numbers after
// converting
public int add(BinaryNumber bn2) {
return convertToDecimal() + bn2.convertToDecimal();
}
// Creating the .sub to subtract the two different binary numbers after
// converting
public int sub(BinaryNumber bn2) {
return convertToDecimal() - bn2.convertToDecimal();
}
}
You just need to increment your bitposition variable.
int bitPosition = 0;
int sum = 0;
for (int i = n.length() - 1; i >= 0; i--) {
sum = sum + (int) Math.pow(2, bitPosition++) * (n.charAt(i) - 48);
}
return sum;
First of all, Java has a built in binary system, using the primitive int type. You can use this by putting 0b before the number in binary form.
If you are doing this for learning purposes, then here's what's happening:
On each iteration, the value of bitPosition is always 0, because you never update it. Of course, you want to increase it with each iteration. This can be done simply by changing
Math.pow(2, bitPosition)
to
Math.pow(2, bitPosition++)
with the ++ after the variable to change it after it is referenced.

Categories