I need to write a java method to calculate an additional value.
I have a candy bar that costs $10 (price). I need to calculate an added value of 20% (ADDED_VALUE) so I do the following:
price + price*ADDED_VALUE or 10 + 10*20%
and I get 12. But now I need to calculate 10% (NEW_ADD_VALUE) on this 12, but I don't know how to do it.
What I've tried so far:
double priceWithAddedValue() {
return price + price * ADDED_VALUE + price * NEW_ADDED_VALUE
}
However the above code returns 13 and I'm suppose to get 13.2.
I think you should refactor this into a general method which takes an initial double and a fraction indicating what should be added:
double addFraction(double initialValue, double fraction) {
return initialValue + fraction*initialValue;
}
After this, it is very easy to do this twice:
addFraction(addFraction(10, 0.2), 0.1);
You could of course split this into multiple statements.
So this would look like this in your example:
double priceWithAddedValue(){
return addFraction(addFraction(price, ADDED_VALUE), NEW_ADDED_VALUE);
}
Hope this helps!
The most important thing you need to focus on is order of operations, especially the function of the parenthesis, since not only is it valuable knowledge to posses for programming but also for day to day life. (if you use math in your day to day life)
What your trying to do is multiply a number, by the addition of, the product of two numbers.
double priceWithAddedValue() {
return (price + price * ADDED_VALUE) * NEW_ADDED_VALUE;
}
Next you should focus on variable types, like float, int, double, char. The problem you're facing with getting 3 instead of 3.2 is due to int only representing integers (. , -2, -1, 0 , 1 , 2 , .). be fine using a double
Related
Trying to convert minutes to seconds with the starting data being a double,
so for example 33.51 seconds (33 mins 51 seconds)
How to convert that to an int when converting to seconeds only
My code for now would accept it if there was no double point to begin with, so i only used ints only
and it seems to work, but when i have that double in there it doesnt, is therre a better approach to it .
Heres my code for now
public class Runner {
//fields setting up the variables
String MembershipID;
String name;
int time ;
//constructor1 filling in the details
public Runner(String Mem, String na, int ti) {
MembershipID = Mem;
name = na; //This
time = ti;
}
public String getMembershipID() {
return MembershipID;
}
public String getName() {
return name;
} //setting it up for the main method from the constructor fields above
public int getTime() {
int mins = time *60;
return mins;
}
public static void main(String[] args) { //initializing the membership name and time,
Runner a = new Runner("RF23", "George Formsby", 33); //Creating a new instance of
Runner, filling out the details from the sample data provided.
Runner b = new Runner("RG89", "Neil Innes", 32);
Runner c = new Runner("ST200", "Sandy Denny", 30); // With mem and na being
represented from my constructor
System.out.println("MembershipID is: " + a.getMembershipID());
System.out.println("Name is: " + a.getName());
System.out.println("Time in seconds: " + a.getTime());
System.out.println("MembershipID is: " + b.getMembershipID());
System.out.println("Name is: " + b.getName());
System.out.println("Time is: " + b.getTime());
System.out.println("MembershipID is: " + c.getMembershipID());
System.out.println("Name is: " + c.getName());
System.out.println("Time is: " + c.getTime());
}
}
Seems like simple enough math.
Convert minutes + seconds to just seconds
int minutes = ...;
int seconds = ...;
int totalSeconds = minutes * 60 + seconds;
Convert minutes (as a double) to seconds
double time = 12.33;
int seconds = (int) (0.5 + time * 60);
Explanation: when rounding to an int, java lops off the decimal parts. We want to round to the nearest second, which can be trivially accomplished (for positive numbers!) by adding 0.5 to it and then casting to int.
NB: See note below!
Convert seconds (as int) to minutes (as double)
int totalSeconds = ....;
double time = time / 60.0;
Explanation: In java, The syntactic construct x / y is considered to be 'integer division' if x and y are both integral data types (byte, short, int, long, or char). It is considered 'floating point division' if either x or y is a floating point type (float or double). integer division will lop off the decimal digits (so, it rounds down for positive results, and rounds up for negative results). Thus, 90 / 2, for example, resolves to 1. Not 1.5. On the other hand, 90 / 2.0 resolves to 1.5, because at least one of the two numbers is a double (2.0 is a double constant, 2 is an int constant). Hence why we divide by 60.0 and not 60.
NB: Important thing to think about: PRECISION.
Computers aren't magical, and double is precisely defined as consisting of exactly 64 bits.
You can't store one of an infinite sequence of options in a finite storage space, so, computers cannot store numbers perfectly. A 64-bit storage space has the ability to give you at most 2^64 different 'options'. If the storage space is storing a number, that means there are at most 2^64 numbers it could possibly store there, and all other numbers therefore simply cannot be represented by it. Somebody needs to go out and define which numbers are 'blessed' - capable of being stored. Then someone needs to define what happens if you attempt to store a non-blessed number in them.
For the integer data types, this is easy: int (32-bit) can store 2^32 numbers. Which numbers are blessed? Simply -2^31 to +2^31 -1. When you attempt to store something above or below it, the numbers just loop around:
int reallyLarge = Integer.MAX_VALUE; // this is 2^31-1.
int surelyThisIsEvenLarger = reallyLarge + 1;
Actually, surelyThisIsEvenLarger is negative number instead. It looped around.
For double and float it is way more complicated. Even between just 0 and 1 there are infinite numbers! The blessed numbers are chosen by more or less throwing darts at the numberline, focusing about half the darts close to 1.0, with fewer and fewer darts hitting the number line as you move away from 1.0. Eventually, at around 2^52, the 'distance' between any 2 darts is higher than 1.0, even.
It's a bit like how we humans do it: We cannot 'represent' 1 divided by 3, at all. 0.333333.... it never ends.
To make matters worse, computers count in binary and not decimal. So, where we humans can e.g. do '1 divided by 10' (that's 0.1, so it is a blessed number in the system of 'a human writes it down in decimal on a bit of paper that has room for about 10 digits'), computers cannot do that, either.
Thus, most of the 'take these number of seconds and turn them into a double' values, are not actually blessed, so it is important to realize what happens when you try to make a double that isn't blessed: The computer will round it off to the closest blessed number. You can't ask for the error (the amount it rounded by), or ask it not to do this; not with double, anyway.
If you do enough back-and-forth math on them, those errors compound and eventually will be flat out wrong. That's one of the many reasons why you should most definitely never, ever use double to store money values. For race monitoring you're running into a similar situation here, best not to use them. Better to pick an atomic unit and store in those. For example, why not store in millis? The current record for fastest mile is 3:43.13. In 'millis', that becomes long fastestMile = 223130; - no need to involve those nasty doubles with their bizarro rounding behaviours.
I'm new to java so please bear with me. I'm trying to get the percentage of wins from total number of games and something I'm doing is way off. My method for getting the percentage is below:
public double winPercentage(int wins, int total)
{
return (wins % total) * 1.00;
}
If I win 52 games out of 254 my answer comes up to 52.0, using my calculator that same answer is 20.47 assuming wins/total*100. If I switch the modulus to / I constantly get 0.0
I've tried a variation of different decimal places and order of operations. I can't seem to get the calculator and method to match up.
The percent sign in wins % total has no relationship to computing a percentage.
To compute percentage in Java, you could write
return 100.0 * wins / total;
Here, 100.0 serves dual purpose:
it rescales the result to percentage points;
it turns the subsequent division into a floating-point one (without which it's an integer division, always returning zero when wins < total).
Java uses % as modulo operator, so it will always return the remainder as a result not percentage.
If we divide integer by integer, then result will not be precise as required for percentage function. E.g. if we try to divide 52 by 254 result will be 0 for an integer not 0.2047, as integer is capable of holding complete numbers only. So to get percentage, you can use double/float as parameter data type like below instead of integer.
public double winPercentage(double wins, double total) {
return wins / total * 100;
}
I'm trying to implement the n-th root algorithm for large numbers without using any predefined functions in Java. No sqrt, no pow, no abs, nothing.
The limitations are:
1. The number can be up to 17 digits.
2. The root's order can be from 2 to 10.
3. The precision of the result should be around 10 decimal points.
Is this do-able?
I've read a lot of answers on similar questions on nth root algorithm, Newton's method, other iterative methods, but most of them use either pow, abs, sqrt or other pre-defined functions.
What I've got still has predefined functions and is something I came up with after being inspired from other posts:
public static double getRoot3(double number){
double guess = 2;
double possibleRoot = Math.abs((guess*guess)-number);
while(possibleRoot> 0.009 ){
possibleRoot = Math.abs((guess*guess)-number);
guess = ((number/guess)+guess)/2.0;
}
return guess;
}
public static void main(String[] args) {
double number = 12;
double result = getRoot3(number);
System.out.println("Number: " + number);
System.out.println("Square root of " + number + ": " +result);
System.out.println("Test: " + result * result );
}
This uses a hard-coded number for the test: 12 and the results are as follows:
Number: 12.0
Square root of 12.0: 3.4641016200294548
Test: 12.000000033890693
So it's working, I'm getting a precision of 7 float points, but if I try to increase the preciion by adding zeroes into the while condition it breaks.
I tried to troubleshoot it and it appears that, at somepoint "possibleRoot" suddenly contains an E among the digits and the condition evaluates to false.
How can I increase the precision and how can I extend it for other roots like cubic or more? This one works only for square root right now.
By using BigDecimal you will avoid double/float precision issues, see Square root of BigDecimal in Java .
I don't think you will get it more precise. Java and other languages do have the "Floating Point Problem". It means, that whenever you use floats/doubles it will be slightly different from the original number. That comes from the limitations to represent numbers in memory.
Also, the "E" indicates that the number on the left side of it has to be multiplied by 10^x, where x is the right number of the "E". This will occur when the number has too many digits to display. Example:
125.34E3
= 125.34 * 10^3
= 125.34 * 1000
= 125340.0
In my program i'm posting the payment amount value to controller and i'm converting that value to Integer. Because I need to convert this value to cents before calling web service.
I'm using java and convert String to Integer code given below
(int)(Double.parseDouble(httpRequest.getParameter(PAYMENT_AMOUNT).trim()) * 100);
payment.jsp
page look like this
Payment Amount: <input type="text" id="paymentAmount" name="paymentAmount" value="1.00" />
For many input values it gives the correct output.
But for some values like 8.03 as input it return 802 as output value . This happens in 9.03,9.04 ,10.03,10.04,11.03 etc ... what could be the reason for this issue?
You need to round the result. The problem you have is that floating point numbers are almost but not exactly the number it appears when printed as a string. This shows up as a problem when you perform calculations.
I suggest you try
(int) Math.round( Double.parseDouble( httpRequest.getParameter(PAYMENT_AMOUNT).trim()) * 100);
In your specific case, you can see with BigDecimal what the actual representation of a double is
double d = 8.03;
BigDecimal bd = new BigDecimal(d);
System.out.println("bd: " + bd);
double d100 = d * 100;
System.out.println("d100: " + d100);
int i100 = (int) d100;
System.out.println("i100: " + i100);
int r100 = (int) Math.round(d100);
System.out.println("r100: " + r100);
prints
bd: 8.0299999999999993605115378159098327159881591796875
d100: 802.9999999999999
i100: 802
r100: 803
So you can see the actual value of 8.03 is slightly less than 8.03 which means however that when you * 100 and round down it means that you get 802 not 803 as expected.
The best solution is to round the result which finds the closest representable value.
As a side note, you might want to reconsider using int types to store cent values esp when dealing with large numbers.
To add more to earlier answers on floating-point issues in Java, and the need for BigDecimal, refer to some explanation here:
http://www.drdobbs.com/jvm/javas-floating-point-imprecision/240168744
You can change your code to:
(new BigDecimal(httpRequest.getParameter(PAYMENT_AMOUNT).trim(), MathContext.DECIMAL64)).multiply(new BigDecimal(100, MathContext.DECIMAL64)).intValue()
Another note: I would be cautious about assuming that you will get a String object back in the getParameter() call above esp. if someone is attempting to call your service without passing the PAYMENT_AMOUNT parameter.
I'd like to round manually without the round()-Method.
So I can tell my program that's my number, on this point i want you to round.
Let me give you some examples:
Input number: 144
Input rounding: 2
Output rounded number: 140
Input number: 123456
Input rounding: 3
Output rounded number: 123500
And as a litte addon maybe to round behind the comma:
Input number: 123.456
Input rounding: -1
Output rounded number: 123.460
I don't know how to start programming that...
Has anyone a clue how I can get started with that problem?
Thanks for helping me :)
I'd like to learn better programming, so i don't want to use the round and make my own one, so i can understand it a better way :)
A simple way to do it is:
Divide the number by a power of ten
Round it by any desired method
Multiply the result by the same power of ten in step 1
Let me show you an example:
You want to round the number 1234.567 to two decimal positions (the desired result is 1234.57).
x = 1234.567;
p = 2;
x = x * pow(10, p); // x = 123456.7
x = floor(x + 0.5); // x = floor(123456.7 + 0.5) = floor(123457.2) = 123457
x = x / pow(10,p); // x = 1234.57
return x;
Of course you can compact all these steps in one. I made it step-by-step to show you how it works. In a compact java form it would be something like:
public double roundItTheHardWay(double x, int p) {
return ((double) Math.floor(x * pow(10,p) + 0.5)) / pow(10,p);
}
As for the integer positions, you can easily check that this also works (with p < 0).
Hope this helps
if you need some advice how to start,
step by step write down calculations what you need to do to get from 144,2 --> 140
replace your math with java commands, that should be easy, but if you have problem, just look here and here
public static int round (int input, int places) {
int factor = (int)java.lang.Math.pow(10, places);
return (input / factor) * factor;
}
Basically, what this does is dividing the input by your factor, then multiplying again. When dividing integers in languages like Java, the remainder of the division is dropped from the results.
edit: the code was faulty, fixed it. Also, the java.lang.Math.pow is so that you get 10 to the n-th power, where n is the value of places. In the OP's example, the number of places to consider is upped by one.
Re-edit: as pointed out in the comments, the above will give you the floor, that is, the result of rounding down. If you don't want to always round down, you must also keep the modulus in another variable. Like this:
int mod = input % factor;
If you want to always get the ceiling, that is, rounding up, check whether mod is zero. If it is, leave it at that. Otherwise, add factor to the result.
int ceil = input + (mod == 0 ? 0 : factor);
If you want to round to nearest, then get the floor if mod is smaller than factor / 2, or the ceiling otherwise.
Divide (positive)/Multiply (negative) by the "input rounding" times 10 - 1 (144 / (10 * (2 - 1)). This will give you the same in this instance. Get the remainder of the last digit (4). Determine if it is greater than or equal to 5 (less than). Make it equal to 0 or add 10, depending on the previous answer. Multiply/Divide it back by the "input rounding" times 10 - 1. This should give you your value.
If this is for homework. The purpose is to teach you to think for yourself. I may have given you the answer, but you still need to write the code by yourself.
Next time, you should write your own code and ask what is wrong
For integers, one way would be to use a combination of the mod operator, which is the percent symbol %, and the divide operator. In your first example, you would compute 144 % 10, resulting in 4. And compute 144 / 10, which gives 14 (as an integer). You can compare the result of the mod operation to half of the denominator, to find out if you should round the 14 up to 15 or not (in this case not), and then multiply back by the denominator to get your answer.
In psuedo code, assuming n is the number to round, p is the power of 10 representing the position of the significant digits:
denom = power(10, p)
remainder = n % denom
dividend = n / denom
if (remainder < denom/2)
return dividend * denom
else
return (dividend + 1) * denom