Textfield JavaFX with dynamic mask for monetary values - java

I'm trying to create a textfield Java FX for a financial application. I would like this texfield to follow the same pattern as the numerical fields found in ATMs. For example: in ATM the initial value in the value field is "0.00". When the user types the value he wants to extract, for example, typing starts from right to left, replacing the leading zeros ... For example, I want to withdraw $ 99.90 (user type the 9 key three times and the 0 key once) and it happens that :
0.09 -> 0.99 -> 9.99 -> 99.90
Anyone have an idea how to create this mask?
I've seen several answers on similar topics but I could not adapt any of them to my project (maybe because I'm a beginner in Java and I'm still learning about the String class, textfield methods, etc.)
Thank you in advance for your attention.
P.S .: I am not yet fluent in English, so if there is any grammatical error in this message, it was because of the Google Translator I used to write

The basic algorithm is the following (pseudo code):
float value = 0; // The initial value is 0
// On Input
void input( int digit ){ // This is invoked when the user presses a digit on the keyboard
// You multiply the current value by ten and add the new digit
value *= 10;
value += digit * 0.01;
}
You will get the following steps for the 9990 input:
1: (0.00 * 10) + (9 * 0.01) = 0.09
2: (0.09 * 10) + (9 * 0.01) = 0.99
3: (0.99 * 10) + (9 * 0.01) = 9.99
4: (9.99 * 10) + (0 * 0.01) = 99.90

Related

Rounding problem in Java. Why am i not getting the expected results in this case?

I have a plugin that i made for Minecraft. It is used for massive ender dragon fights to divide the EXP fairly among everybody, based on the damage dealt.
It works but there's a hiccup that makes the equation miss experience.
Here's the code:
private void divideExpAmongstPlayersBasedOnDamageDealt(int exp, Map<Player, Double> damageMap) {
double totalDamageDealt = 0.0d;
for (Double value : damageMap.values()) {
totalDamageDealt += value;
}
while (exp > 0 && !damageMap.isEmpty()) {
Player maxHitterInList = Collections.max(damageMap.entrySet(),
Comparator.comparingDouble(Map.Entry::getValue)).getKey();
double damageShare = damageMap.get(maxHitterInList) / totalDamageDealt;
int expShare = (int) Math.round(exp * damageShare);
if (expShare == 0)
break;
if (maxHitterInList.isOnline()) {
sendPlayerMessage(maxHitterInList, damageShare, expShare);
maxHitterInList.giveExp(expShare);
}
exp -= expShare;
damageMap.remove(maxHitterInList);
}
}
It finds the max hitter, awards them their share of EXP and removes them from the list, until there is no more EXP left to give.
The problem is that it misses points, forcing me to add && !damageMap.isEmpty() to the while condition to avoid exceptions.. It prints the percentages accurately always (the sum adds up to 100).
Im thinking it has to do with the Math.round function, although i am in the dark as how to debug this. When i do the calculations by hand they work out.
Example (this literally happened): A mob grants 10 exp. Player1 did 57% of damage, Player2 did 43%. The percentage values get printed correctly, yet Player1 receives 6 EXP and Player2 receives 2?? Last time i checked 0.57 * 10 equals 5.7 = 6 and 0.43 * 10 equals 4.3 = 4.
What am i missing? Does it have to do with the round function or the way doubles work?
Thanks
This is not a rounding issue but you are using the wrong value in your calculation.
You wrote "Last time i checked 0.57 * 10 equals 5.7 = 6 and 0.43 * 10 equals 4.3 = 4" but the formula you use is
int expShare = (int) Math.round(exp * damageShare);
and you update exp for each iteration of the loop
exp -= expShare;
which means for your second player exp is for 4 and not 10 as you assumed in your example so the real calculation is 0.43 * 2 which rounded is 2
So you need to separate between the variable used in the condition for the while and the one used in the calculation.

Computing Pi in Java

This weeks assignment in programming is to compute Pi in java using this as the basis for the assignment:
(for 80% of the marks):
USING A WHILE OR A DO-WHILE LOOP write a program to compute PI using the following equation:
PI = 3 + 4/(2*3*4) - 4/(4*5*6) + 4/(6*7*8) - 4/(8*9*10) + ...
Allow the user to specify the number of terms (5 terms are shown) to use in the computation.
Each time around the loop only one extra term should be added to the estimate for PI.
(for 20% of the marks):
Alter your solution from part one so that the user is
allowed to specify the precision required between 1 and 8 digits
(i.e. the number of digits which are correct; e.g. to 5 digits PI is 3.14159),
rather than the number of terms. The condition on the loop should be altered so that it
continues until the required precision is obtained. Note that you need only submit this
second version of the program (assuming you have it working).
I'm only able to use the above method to compute Pi, as thats what the lecturer wants. Ive got this so far, although the code keeps giving me the same wrong answer for every even number and a different wrong answer for each odd number. Im still on part one as i havent got the right answer yet to be able to progress onto part 2.
All help would be great, as the program needs to be submitted by tueday.
Thanks in advance!
import java.util.Scanner;
public class ComputePI {
public static void main(String[] args) {
System.out.print( "Please enter the amount of decimal "
+ "digits of PI, you would like to set it too");
Scanner termScan = new Scanner( System.in );
int term = termScan.nextInt();
termScan.close();
double pi = 3.0;
int loopCount = 2;
int number = 2;
while ( loopCount <= term )
{
if (loopCount % 2 == 0)
{
pi = pi + ( 4.0/ ((number) * (number+1) * (number+2)) );
}
else
{
pi = pi - ( 4.0 / ((number) * (number+1) * (number+2)) );
}
number = number + 2;
loopCount++;
}
System.out.print( "The Value of Pi in " + term +
" terms is equal to " + pi);
}
}
I am not going to give you code (you can figure it out for yourself, I'm certain), but I'll give you the location for where to look for the problem.
In the negative terms, you are adding 2 to each number multiplied together. However, you are adding 2 to each number in every iteration of the loop: the numberXXX + 2 part should probably just be numberXXX.
You are now also incrementing the numberXXX variables when loopCount is 1. In fact, the if (loopCount == 1) part is unnecessary, since you already initialize pi. You should just remove the if block there and switch the loopCount % 2 == X blocks around.
I'll also give you general advice about things you might want to consider in your code.
You don't need constants like 4.0 to be in a variable. Just replace fourConstant with 4.0.
You don't need to use an else if for the third block: if loopCount % 2 is not 0 it is definitely 1.
loopCount can only get integer values, so it should probably be an int. A double just consumes extra memory (this is not too problematic here, but may be in large programs) and can in some cases lead to errors (too large numbers may cause rounding errors).
You don't need three variables for numberOne, numberTwo and numberThree; they can always be represented as numberOne, numberOne + 1 and numberOne + 2.
You are incrementing the variables numerOne,numberTwo,numberThree in case the loopCount = 1. In this case you should just continue the loop without incrementing this variables. So change this:
if (loopCount == 1 )
{
pi = 3.0;
}
in:
if (loopCount == 1 )
{
pi = 3.0;
loopCount++;
continue;
}
And change this:
pi = pi - ( fourConstant / ((numberOne+2)*(numberTwo+2)*(numberThree+2)));
into:
pi = pi - ( fourConstant / ((numberOne)*(numberTwo)*(numberThree)));
Or you could just initialize loop count to 2 and remove the first if.
Additionally it would be better is loopCount and term were integer variables instead of Double since they are going to hold only integer values.

displaying list of powers program

I really need help with creating a program that displays a list of powers
here is the input and the output:
Input to the application is to include numbers to represent the following:
base
exponent (between 1 and 10)
Output is to list the number that you entered as a base and find the powers for that base from 1 up to the ending exponent number that is input.
I'm almost done the program, but the problem is that the program only calculate the base to the power without listing a list of powers.
I know i'm missing something in my loop
here is my code
double baseIn, exponentIn;
baseIn = Integer.parseInt(txtBase.getText());
exponentIn = Integer.parseInt(txtExponent.getText());
// power = (int) Math.pow(baseIn, exponentIn);
for (int i = 1; i <= exponentIn; i++) {
txtArea.setText(Integer.toString((int) baseIn)+ "to the power of " + i + "=" + Math.pow(baseIn, i) );
}
The following is a recursive solution. Explained in steps. Assuming you want 2^4
1) we call power(2,4)
2) power(2,4) calls power(2,3)
3) power(2,3) calls power(2,2)
4) power(2,2) calls power(2,1)
5) power(2,1) calls power(2,0)
6) power(2,0) returns 1
7) power(2,1) returns (2 * 1) or 2
8) power(2,2) returns (2 * 2) or 4
9) power(2,3) returns (2 * 4) or 8
10) power(2,4) returns (2 * 8) or 16
public static int power(int base, int power){
if (power == 0)
return 1;
else
return base * power(base, power-1);
}
One problem could be that you overwrite the test string of the output text area in each iteration of the loop, so that at the end -- probably without seeing anything else, because your code happens so fast that no repaint occured -- you, only see the last output.
Use a stringbuilder, append the string of each iteration, and only display the combined result after the loop.
Or use the already existing functionality
textArea.append(text + newline);
see for instance Java Swing: Approach for dynamically appending text in text area, have scrollbar update

Generating the list of random numbers with certain average difference

I have to generate a list of random numbers and they have to have a given average difference. For example, a given average difference is 10, so these numbers are good: 1 3 5 9 15 51. What I do, is multiply the given average difference by 2 and add 1. Like this:
while (i <= 50000)
{
i += Math.random() * givenAverageDiff * 2 + 1;
list.add(i);
}
But I never get 5000 or more. In fact, it's always 4,850 or less. Why? Let's say givenAverageDiff is 10. What's my mistake? How can I fix it?
P.S. Implementation in C or PHP is also good for me.
Because you are doing "+ 1".
Let us calculate the expected difference:
E(2*10*x+1)= 2*10*E(x)+1 = 2*10*0.5+1 = 10+1. So, on an average you will get 50000/11 numbers.
You need to pick something whose expected value is equal to 10. Change it to the following and it should work:
while (i <= 50000)
{
i += Math.random() * (givenAverageDiff-1) * 2 + 1;
list.add(i);
}
Think about it in terms of the ranges you create. With your current calculation,
i += Math.random() * givenAverageDiff * 2 + 1;
you are adding between 1 and 2*givenAverageDiff to your number. The sum of 1 through 2x is (2x)(2x+1)/2, and since there are 2x options we divide by 2x to get (2x)(2x+1)/(2*2x) = (2x+1)/2 = x + 0.5.
So what you want is to have 2x+1 options, which is easiest by using a range of [0,2*x]. You can get that by adding parenthesis:
i += Math.random() * (givenAverageDiff * 2 + 1);
If you want it to always increase, then you either need use a non-uniform distribution, or a uniform distribution with a smaller range. To get a range [n,2*x-n] use
i += Math.random() * ((givenAverageDiff - n) * 2 + 1) + n;
If you use a negative value for n you can widen the range, making it possible for numbers to decrease as well.

How do math equations work in Java?

When I do something like this
int test = 5 + 3 * (4 - 1) / 2;
I get 9. I suspected this was because int rounds down. However, when I do this
float test = 5 + 3 * (4 - 1) / 2;
I also get 9. However, when I do this
float test1 = 5;
float test2 = 4.5;
float test = test1 + test2;
Test finally outputs 9.5. Could someone explain the logic behind this? Why don't I get 9.5 in the second example? Thanks.
In your second example, although you are assigning the result to a variable of type float, the calculation itself is still performed exactly the same way as the first example. Java does not look at the destination variable type to determine how to calculate the right hand side. In particular, the subexpression 3 * (4 - 1) / 2 results in 4.
To fix this, you can use floating point literals instead of all integers:
float test = 5 + 3 * (4 - 1) / 2.0f;
Using 2.0f triggers floating point calculations for the arithmetic expression.
Although you represent the result of 5 + 3 * (4 - 1) / 2 in a float, the actual evaluation is done with the precision of an integer, meaning that the division of 9 / 2 returns 4 rather than the 4.5 you would receive if they were evaluated as floats.
Expressions have their own type. So start with:
5 + 3 * (4 - 1) / 2
Each value has its own type. This type happens to be int, so this is the same as:
((int)5) + ((int)3) * (((int)4) - ((int)1)) / ((int)2)
Making it clearer that we're dealing with ints. Only after this is evaluated as 9 does it get assigned to a float.
The short answer is that integer types operate on modular arithmetic, with modulus 1, and discard the remainder.
Since you cast test as an integer, modular arithmetic is employed with modulus 1 (e.g. 9.5 mod 1),
int test = 5 + 3 * (4 - 1) / 2;
With a 32-or-64 bit float this would give 9.5; however, because you have cast test as an int, the remainder is discarded, and the value referenced by test is 9.

Categories