Big Decimal numbers subtraction is not working - bigdecimal

I am facing simple issue in below program. In below code I am just subtracting numbers and expected output is "89.50" but it is printing 90. May I know the reason and help me with code to get expected output.
public class BigDecimal_Prb {
public static void main(String[] args) throws java.lang.Exception
{
MathContext mc = new MathContext(2);
List<BigDecimal> list = new ArrayList<BigDecimal>();
list.add(BigDecimal.valueOf(30));
list.add(BigDecimal.valueOf(120.00));
BigDecimal [] nums = (BigDecimal[]) list.toArray(new BigDecimal[0]);
BigDecimal reaminingAmt=nums[1].subtract(nums[0], mc);
BigDecimal dedAmt=new BigDecimal(0.5);
BigDecimal ans = reaminingAmt.subtract(dedAmt,mc);
System.out.println(ans);
}
}

Subtraction certainly works, but the other things you do cause the "unexpected" result.
A MathContext contains two main elements: a precision and a rounding mode. I guess you understood the rounding mode, but not the precision.
The precision is the number of significant digits of a BigDecimal. In other words, if you set it to 2, you can expect the number to be rounded to two digits, i.e. 90. If you want a certain number of digits after the decimal point, use the scale:
BigDecimal ans = reaminingAmt.subtract(dedAmt).setScale(2);

yes. Finally got it.
No it's not a scaling issue. The "solution" I found has the side-effect of changing the result of the BigDecimal.toString() method. However, the intent of setScale() is to fine-tune the results of internal calculations performed on the BigDecimal value. If you only want the scale of your BigDecimal to be 2 because that's all you need for calculation results to be acceptable, that's fine, set the scale. But if you're using setScale() so that your output will show "120.00" instead of "120.0," then you're using the wrong approach and doing it for the wrong reasons, IMO.
If you need the scale of 2, change all your instance creations to use the BigDecimal(String) constructor. That will retain the .00 part, and you will then get the scale of 2 you have been looking for.
public class BigDecimal_Prb {
public static void main(String[] args) throws java.lang.Exception
{
MathContext mc = new MathContext(4, RoundingMode.HALF_DOWN);
List<BigDecimal> list = new ArrayList<BigDecimal>();
list.add(BigDecimal.valueOf(30));
list.add(BigDecimal.valueOf(120.00));
BigDecimal [] nums = (BigDecimal[]) list.toArray(new BigDecimal[0]);
BigDecimal reaminingAmt=nums[1].subtract(nums[0], mc);
BigDecimal dedAmt=new BigDecimal(0.5);
BigDecimal ans = reaminingAmt.subtract(dedAmt,mc).setScale(2, RoundingMode.HALF_DOWN);
System.out.println(ans.toString());
}
}

Related

Need to convert String to Float variable using Camel-Bindy Format

A test file with delimited Data and one of the field is amount and it arrives as a string. To be converted to float. As per camel-bindy i tried a way, but ended with same value without precesions.
Input : 12345678
#DataField(name="AMT", trim=true, pos = 15 , precision=2)
private BigDecimal amount;
Route:
.unmarshal().bindy(BindyType.Csv, Test.class)
O/P:
12345678.00
Its not getting converted to 123456.78
Please help me with any suggestions.
Annotation #DataField provides another method implementation which supports this kind of feature,
#DataField(name="AMT", trim=true, pos = 15 , precision=2, impliedDecimalSeparator = true)
private BigDecimal amount;
impliedDecimalSeparator decides the decimal position for incoming string field and converts as required.

Get sets of six unique combinations from an array given the range

I do have a problem, i have numbers from 1-49, now the question here is how do i get the maximum number of random sets of six from the given sample. like
int[] a1 = { 1, 2, 3 ,5,6,7 ... 49};
how many unique combination of numbers or arrays can i get from that one big array from 1 to 49 like below
1,2,3,4,5,6
2,1,4,5,8,9
2,1,0,2,4,5
................
What am trying to get is the maximum output or number of possible unique arrays with a length of six i could get . to be honest i have tried writing a loop that reads through the array, but how to capture six random digits is where am stuck i can go any further than
for(int x=0;<a1.length;x++)
{
// here i believe i must turn the captured information
// into a muti dimentional array to cpature like '1,2,3,4,5,6' but how. am stuck
}
If I understand your question correctly, what you need is the binomial coefficient n! / k! (n - k)!, which in this case would be 49! / (6! * (49 - 6)!) = 13983816. No need to write code if the only thing you want to know is the number of possible combinations.
If you really wanted to list all of them, you'd need a little patience. One way to achieve this is via a recursive approach:
public class NOverK {
private static final int[] numbers = new int[6];
private static final int MAX = 49;
private static void output() {
System.out.println();
for (int n : numbers) {
System.out.print(n + " ");
}
}
private static void allCombinations(int x, int start) {
if (x > 0) {
for (int i = start; i <= MAX; i++) {
numbers[numbers.length - x] = i;
allCombinations(x - 1, i + 1);
}
} else {
output();
}
}
public static void main(String[] args) {
allCombinations(6, 1);
}
}
This question has been asked at Stack Overflow a few times in the past. For example, look at this answer:
Click here: Algorithm to return all combinations of k elements from n
The answers to this question contain numerous solutions of your question in different programming languages (Java, Python, C, C# etc.), too. Check out or adjust a solution that meets your requirements.
You can search for other questions/answers in Stack Overflow (search field in upper right corner) with keywords
[algorithm] [combinations]
A Google search would lead to numerous solutions of your question, too. Try with keywords as follows:
java algorithm combinations without repetition
or
c# algorithm combinations without repetition

Learning algorithm for sigmoid Perceptron failing - Handwriting recognition

I'm trying to do handwriting recognition with a single layer of perceptrons, using the MNIST database in Java. Each perceptron is assigned to recognise a digit (so 10 perceptrons). They are each trained randomly on each of 50,000 samples for a number of epochs. When testing, the perceptron with the highest rate is selected (ie the one that is most confident that it is correct).
Using this method I am consistently getting 93.5% accuracy. However, I think to improve I'll need to add hidden layers, and implement backpropogation. When using the Sigmoid (squashing) function to calculate on the forward pass of my single layer network, it works wonderfully. However when I change my backwards pass (learning) function to match back-propogation I get ~70% accuracy. Can someone check over my algorithms to make sure this is correct?
I got the algorithm from a few places, and I think it is the same. For example this one: http://www.webpages.ttu.edu/dleverin/neural_network/neural_networks.html
Note I am treating the last weight as a bias. The 'error' fed into the learn function is just the desired result minus the actual result. example is the same array as input - the greyscale of each pixel in the digit.
Forward pass:
public final double apply( double[] input ) {
double ret = 0;
for (int i=0; i<wei.length-1; i++){
ret = ret + input[i]*wei[i];
}
ret+=wei[wei.length-1];
//apply squashing function
ret = 1/(1+Math.exp(-ret));
return ret;
}
Learning Function (backwards Pass)
public final void learn( double error, double result, double[] example, double alpha ) {
for (int i=0; i<wei.length-1; i++){
//wei[i] = wei[i] + alpha*error*example[i]; //This was original learning function - it gives 93.5% accuracy
wei[i]=wei[i]+ alpha* error * example[i]*result*(1-result); //This line gives ~70% accuracy
}
//wei[wei.length-1] += alpha*error; //this line works for bias
wei[wei.length-1]=wei[wei.length-1]+ alpha* error * 1*result*(1-result); //again, this makes results inaccurate
}
I get best explanation about the algorithm and the implementation in here http://visualstudiomagazine.com/articles/2013/03/01/pattern-recognition-with-perceptrons.aspx this morning. It explains detailed one by one perceptron source code in C# for character recognition.

Integrating cos(x)/sqrt(x) between 0 and infinity to a user defined precision

So I'm trying to do what I've said above. The user will enter a precision, such as 3 decimal places, and then using the trapezium rule, the program will keep adding strips on until the 3rd decimal place is no longer changing, and then stop and print the answer.
I'm not sure of the best way to approach this. Due to the function being sinusoidal, one period of 2PI will almost be 0. I feel like this way would be the best way of approaching the problem, but no idea of how to go about it. At the moment I'm checking the y value for each x value to see when that becomes less than the required precision, however it never really goes lower enough. At x = 10 million, for example, y = -0.0002, which is still relatively large for such a large x value.
for (int i = 1; i < 1000000000; i++)
{
sumFirstAndLast += func(z);
z += stripSize;
count++;
printf("%lf\n", func(z));
if(fabs(func(z))<lowestAddition/stripSize){
break;
}
}
So this above is what I'm trying to do currently. Where func is the function. The stripSize is set to 0.01, just something relatively small to make the areas of the trapeziums more accurate. sumFirstAndLast is the sum of the first and last values, set at 0.001 and 1000000. Just a small value and a large value.
As I mentioned, I "think" the best way to do this, would be to check the value of the integral over every 2PI, but once again not sure how to go about this. My current method gives me the correct answer if I take the precision part out, but as soon as I try to put a precision in, it gives a completely wrong answer.
For a non-periodic function that converges to zero you can (sort of) do a check of the function's value and compare to a minimum error value, but this doesn't work for a periodic function as you get an early exit before the integrand sum converges (as you've found out). For a non-periodic function you can simply check the change in the integrand sum on each iteration to a minimum error but that won't work here either.
Instead, you'll have to do like a few comments suggest to check for convergence relative to the period of the function, PI in this case (I found it works better than using 2*PI). To implement this do something like the following code (note I changed your sum to be the actual area instead of doing it at the end):
sumFirstAndLast = (0.5*func(a) + 0.5*func(b)) * stripSize;
double z = a + stripSize;
double CHECK_RANGE = 3.14159265359;
double NextCheck = CHECK_RANGE;
double LastCheckSum = 0;
double MinError = 0.0001;
for (int i = 1; i < 1000000000; i++)
{
sumFirstAndLast += func(z) * stripSize;
if (z >= NextCheck)
{
if (fabs(LastCheckSum - sumFirstAndLast ) < MinError) break;
NextCheck += CheckRange;
LastCheckSum = sumFirstAndLast;
}
z += stripSize;
count++;
}
This seems to work and give the result to the specified accuracy according to the value of MinError. There are probably other (better) ways to check for convergence when numerically integrating a periodic function. A quick Google search reveals this paper for example.
The integral of from 0 to infinity of cos(x)/sqrt(x), or sin(x)/sqrt(x) is well known to be sqrt(pi/2). So evaluating pi to any number of digits is easier problem. Newton did it by integrating a quarter circle to get the area = pi/4. The integrals are evaluated by the methods of complex analysis. They are done in may text books on the subject, and on one of my final exams in graduate school.

How to use scanner to input into a 2 dimensional array?

I'm taking a online Java course and attempting my 2nd assignment. The first assignment was not difficult but this one is just way over top. I honestly don't know where to begin. The problem is this class is online, basic instructions are to read these chapters and then write the program. There's not much guidance since my instructor is not with me physically.
I've never used scanner before or created two dimensional arrays. My instructor gives notes on what to do in each area of his skeleton program but I don't have a clue which one to start with.
Your task is to implement a similar scheme to store poynomials of any number of terms, such that the
number of terms and the components (coefficient, variable and exponent) of every term are entered from
the keyboard.
To implement the interactive input we will using the Java class Scanner, defined in the java.utils
standard package. The Scanner class can be used in Java to read data types from a file. Since the input
console (keyboard) is treated as the file called System.in, we can create a Scanner for that input stream
as new Scanner (System.in), as shown below. Once you define a Scanner object, using its method
next() you can read Strings from the file/keyboard.
The incomplete program below is your assignment. You are supposed to complete without changing the
existing code.
Your output should be the terms of the polynomial entered by the user, separated by + signs.
Additional instructions in the code below, that you will change to achieve the requested functionality.
import java.util.Scanner;
public class Polynomials {
public static void storeTerm (int coeff, String var, int exp, String poly[][], int
where){
//ENTER THE COEFFICIENT, VARIABLE AND EXPONENT INTO THE
//ARRAY POLY THAT REPRESENTS THE POLYNOMIAL, AT POSITION "where"
//THAT RANGES BETWEEN INDEX 0 AND POLY.LENGTH-1
}
public static void printTerm (String [] term) {
//PRINTS EACH TERM
//IF THE EXPONENT OF THE VARIABLE IS 1 DOE NOT PRINT THE EXPONENT
//IF THE EXPONENT IS 0, PRINT ONLY THE COEFFCIENT
//IF THE COEFFICIENT IS 1, DO NOT PRINT IT, UNLESS IT IS THE ONLY COMPONENT OF
//THE TERM
}
public static void printPolynomial(String terms[][]){
//CALL printTerm in a loop to print all terms separated by + signs
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int numberTerms = 0;
System.out.println("How many terms?");
numberTerms = sc.nextInt();
//ENTER HERE THE CODE TO CREATE THE TWO DIMENSIONAL ARRAY NEEDED TO STORE THE TERMS
//OF THE POLYNOMIAL
if (numberTerms <= 0)
System.out.println("Error: Polynomials must have at least one term");
else {
String coeff = "", variable="", exponent="";
for (int i = 1; i<= numberTerms; i++) {
System.out.println("Enter the coeffcient for term " + i);
coeff = sc.next();
System.out.println("Enter the variable name:");
variable = sc.next();
System.out.println("Enter the expoenent for this term");
exponent = sc.next();
//CALL METHOD storeTerm TO INPUT THIS NEW TERM INTO THE ARRAY WRITE THE CORRECT
//CALL TO storeTerm HERE
}
printPolynomial(terms);
}//endf if
}//end main
}//end class
Again not looking for answers. Just where to start. Then I'll post my results.
It is not completely obvious where the two-dimensional array enters, since the structure hints at a list of terms.
You will need to define a data structure, in Java as a class, to hold the information for each term.
From the description, it seems that the input are polynomials of the form 3x^2+5y^7 and not xy+3y^2z^3.

Resources