I have this function and I was trying to get a list of all the calculations.
f(x) = (100)(1.1)^X
How do I calculate this out in Java. I tried a for loop to get the value of x and the end result of y, but that didn't work. Might have been my code inside. I tried to get the exponent of 1.1 and the multiply that by 100, is this correct?
for(int i = 1; i<=15; i++){
int expcalc = (int) Math.pow(1.1, i);
int finalcalc = price * expcalc;
System.out.println(" " + finalcalc);
}
What am I doing wrong here?
Why are you casting the result as an int? That will drop everything past the decimal point. Declare expcalc and finalcalc as double instead to obtain an accurate result.
double expcalc = Math.pow(1.1, i);
double finalcalc = price * expcalc;
Use BigDecimal if you're using pow() and decimal values, and ESPECIALLY ON MONEY
Assuming your interpretation is correct,
BigDecimal price = new BigDecimal("0.0"); //change this value to your price
for(int i = 1; i<=15; i++){
BigDecimal expcalc = new BigDecimal("1.1").pow(i);
BigDecimal finalcalc = price.multiply(expcalc);
System.out.println(" " + finalcalc);
}
Avoid using double/float on monetary computations.
Related
I'm getting exponential value in the result of expression where I'm adding double with long.
package com.testing;
import java.util.Date;
public class TypeCasting {
public static void main(String[] args) {
long varA = 100000;
long varB = 3000000;
double logVarA = Math.log10(varA); // 5.0
double logVarB = Math.log10(varB); // 6.477121254719663
long timeStampInSec = new Date().getTime() / 1000;
System.out.println(timeStampInSec); // 1552543503
double totalValue = logVarA + logVarB + timeStampInSec;
System.out.println(totalValue); // 1.5525435144771214E9
double finalScoreDampingFactor = 1000;
double finalScore = totalValue / finalScoreDampingFactor;
System.out.println(finalScore); // 1552543.5144771214
}
}
In totalValue variable why I'm getting 1.5525435144771214E9 value and when I'm deviding it with 1000, getting 1552543.5144771214.
Can any body please explain ?
A number has the same value, regardless of how it's represented. What you see printed as a String is just a representation of the number.
The JVM has decided, for whichever reason, that the number should be printed in exponential form. If you want to force it to print it differently, you can use printf.
double totalValue = logVarA + logVarB + timeStampInSec;
System.out.printf("%f%n", totalValue); // 1552547672.477121
The notation EX means "times 10 to the power of X".
So the original number was 1552543514.4771214.
1.5525435144771214E9
is 1552543514.... divided by 1000 is 1552543....
Is it possible that you misinterpreted the 1.5525435144771214E9 ?
I am using the "think java" book and I am stuck on exercise 7.6. The goal here is to write a function that can find . It gives you a couple hints:
One way to evaluate is
to use the infinite series expansion:
In other words, we need to add up a series of terms where the ith term
is equal to
Here is the code I came up with, but it is horribly wrong (when compared to Math.exp) for anything other than a power of 1. I don't understand why, as far as I can tell the code is correct with the formula from the book. I'm not sure if this is more of a math question or something related to how big of a number double and int can hold, but I am just trying to understand why this doesn't work.
public static void main(String[] args) {
System.out.println("Find exp(-x^2)");
double x = inDouble("Enter x: ");
System.out.println("myexp(" + -x*x + ") = " + gauss(x, 20));
System.out.println("Math.exp(" + -x*x + ") = " + Math.exp(-x*x));
}
public static double gauss(double x, int n) {
x = -x*x;
System.out.println(x);
double exp = 1;
double prevnum = 1;
int prevdenom = 1;
int i = 1;
while (i < n) {
exp = exp + (prevnum*x)/(prevdenom*i);
prevnum = prevnum*x;
prevdenom = prevdenom*i;
i++;
}
return exp;
} // I can't figure out why this is so inacurate, as far as I can tell the math is accurate to what the book says the formula is
public static double inDouble(String string) {
Scanner in = new Scanner (System.in);
System.out.print(string);
return in.nextDouble();
}
I am about to add to the comment on your question. I do this because I feel I have a slightly better implementation.
Your approach
Your approach is to have the function accept two arguments, where the second argument is the number of iterations. This isn't bad, but as #JamesKPolk pointed out, you might have to do some manual searching for an int (or long) that won't overflow
My approach
My approach would use something called the machine epsilon for a data type. The machine epsilon is the smallest number of that type (in your case, double) that is representable as that number. There exists algorithm for determining what that machine epsilon is, if you are not "allowed" to access machine epsilon in the Double class.
There is math behind this:
The series representation for your function is
Since it is alternating series, the error term is the absolute value of the first term you choose not to include (I leave the proof to you).
What this means is that we can have an error-based implementation that doesn't use iterations! The best part is that you could implement it for floats, and data types that are "more" than doubles! I present thus:
public static double gauss(double x)
{
x = -x*x;
double exp = 0, error = 1, numerator = 1, denominator = 1;
double machineEpsilon = 1.0;
// calculate machineEpsilon
while ((1.0 + 0.5 * machineEpsilon) != 1.0)
machineEpsilon = 0.5 * machineEpsilon;
int n = 0; //
// while the error is large enough to be representable in terms of the current data type
while ((error >= machineEpsilon) || (-error <= -machineEpsilon))
{
exp += error;
// calculate the numerator (it is 1 if we just start, but -x times its past value otherwise)
numerator = ((n == 0) ? 1 : -numerator * x);
// calculate the denominator (denominator gets multiplied by n)
denominator *= (n++);
// calculate error
error = numerator/denominator;
}
return exp;
}
Let me know how this works!
i want to change 2.5 to 2½. Not sure how to change it.
Let say I have “AMZN 2½ 22” in a long text that I have to highlight in java swing textpane but I have values in three variable as below
A = AMZN
B = 2.5
C = 22
Based on this value I will not be able to match so changing B to Rational number (String) and then matching and it’s working fine but I don’t want to do this… it’s just a temp fix.
Can someone help me ?
B = B.toString().replace(".25", "¼")
.replace(".5", "½")
.replace(".75", "¾")
.replace(".375", "⅜")
.replace(".625", "⅜")
.replace(".125", "⅛")
.replace(".875", "⅞")
.replace(".0", "")
.replace(".000", "")
.replace(".00", "");
Thanks
Here's how to print the symbol 'half':
String half = "\u20BD";
System.out.println("2" + half);
determining if a number is an integer plus half is left as an exercise to the reader.
You can swap .0 replaces with a regex (replaceAll("\\.[^1-9]+","" comes to mind), you can move the replaces to a map or utility class, have them happen only when Float.parseFloat(var) doesn't throw NumberFormatException...
But there is no truly better way to do such arbitrary replaces. Those unicode strings have no intrinsic connection with the numbers they represent that you could use.
There are two alternatives for real numbers: double (an approximation of a real number) or BigDecimal (maintaining a precission).
String a = "AMZN";
BigDecimal b = new BigDecimal("2.5");
double b2 = 2.5;
int c = 22;
// %s = string, %f = floating point, %d = digits, %n = newline.
System.out.printf("%s %f %d%n", a, b2, c);
For double you have not really any control but you might format the output (printf) using "%.3f" for a precission of 3 decimals.
In your case you want to represent the numbers using fractions from the Unicode.
Let's do that with the less suited double:
System.out.printf("%s %s %d%n", a, asFraction(b2), c);
static String[] fractionTexts = { "", "¼", "½", ... }; // Maybe char
static double[] fractionValues = { 0.0, 0.25, .5, ... };
static String asFraction(double x) {
if (x < 0) {
return "\u2212" + asFraction(-x); // U+2212 is Unicode minus.
}
long integralPart = (long)x;
double decimalsPart = x - integralPart;
for (int i = 0; i < fractionValues.length; ++i) {
if (almostEqual(decimalsPart, fractionValues[i]) {
decimalPoint = "";
return MessageFormat("{0}", integralPart) + fractionTexts[i];
}
}
return MessageFormat("{0}", x);
}
private boolean almostEqual(double x, double y) {
final double EPS = 0.0001;
return x >= y - EPS && x <= y + EPS;
}
The code uses MessageFormat for thousand separators / decimal separator. For 0.0, 0.00, 0.00ß0 (the same number) it leaves away the numbers explicitly. The java source code must be in the same encoding as the java compiler and be able to hold ¼ and others (like UTF-8).
For the error bearing double I have introduced almostEqual.
the following code calculates change dispensed by a vending machine. My problem? I cant get the change variable to work as the compiler wont let me due to two different data types (int & double conversion). Can anyone please help me solve this problem.
I have tried casting "change" but then it wont print right amount.
For example, if the change is 0.25 cents, change value remains zero..for obvious reasons of course. The problem begins at line 16. I have commented the part giving example as change = 0.25.
public String[] itemList = new String[] {"Water ","Coke ", "Diet Coke", "Iced Tea","Fanta "};
public double[] priceList = new double[] {75,120, 120, 100, 150};
public int[] itemQty = new int[]{10,10,10,10,10};
public int[] coinList = new int[]{100,50,20,10,5};
public int[] coinQty = new int[]{10,10,10,10,10};
public double change;
public double paid;
public void ReturnChange()
{
int Denominations=5;
int coins_dispensed = 0 ;
int[] InitialArray = new int[Denominations];
//My Problem begins here..for example if change is computed
change = 0.25; //change is a global declaration of type double and carries values derived from different function
int change1 = (int)change; //if i cast here, i get change as 0, thus the part that follows, fails to compute coins dispensed.
for (int i=0; i < 5; i++)
{
InitialArray[i] += coinQty[i]; // Copies Coin Quantity to Initial array for difference
}
System.out.println("Your change is "+NumberFormat.getCurrencyInstance().format(Math.abs(change1)) +" which comprises of:"); //OK till here
for (int i=0; i<5; i++)
{
if (coinQty[i]>0) //if a particular denomination is available
{
coins_dispensed = (change1/coinList[i]); //dividing coins dispense with denomination
coinQty[i] -= coins_dispensed; //reduce the quantity of the denomination dispensed
change1 = change1 - (coinList[i] * coins_dispensed); //total the change
}
else // Moves to next denomination if a particular coin runs out
{
coins_dispensed = (change1/coinList[i+1]);
coinQty[i+1] -= coins_dispensed ;
change1 = change1 - (coinList[i+1] * coins_dispensed);
}
}
if (change1 != 0) // In the case not enough coins to make change, selection is ignored.
{
System.out.println("\n\n\t Sorry. The machine doesnt have enough coins to make up your change. Your last transaction has been ignored.");
}
else
{
for (int i=0; i<Denominations; i++)
{
coins_dispensed = InitialArray[i] - coinQty[i];
System.out.println( "\n\t\t\t" + coins_dispensed +" of "+ coinList[i] + " cents coins");
}
}
}
You should use use integers everywhere but count in cents not dollars. Just divide your numbers by 100 when you print them.
This is because floats and doubles cannot accurately represent the base 10 multiples used for money and will introduce rounding errors, particularly when multiplying to calculate interest rates for example.
See Why not use Double or Float to represent currency? for more information and discussion.
It seems all your variables hold prices in cents (i guess a coke is not 120 $). But your change is apparently specified in dollars. So what you could do is multiply change by 100 and then cast it to int.
Like that:
int change1 = (int) (change * 100); // convert dollars to cents and cast to int
If you need to output change1 in dollars (and not cents) at some point, you have to convert it back:
float result = change1 / 100.0f;
I have to calculate PI to a certain number of decimals (given in variable zecimale), using the Leibniz formula for calculating PI. I don't know why, but not a single addition or subtraction on that BigDecimal isn't modifying the value of PI.
Why is this?
int zecimale = 0;
if (args.length > 0) {
try {
zecimale = Integer.parseInt(args[0]);
} catch (NumberFormatException e) {
System.err.println("Argument" + " must be an integer");
System.exit(1);
}
}
long start = System.nanoTime();
double numitor = 1;
BigDecimal numitor1 = new BigDecimal(1/numitor);
BigDecimal pi = new BigDecimal(1);
for(int x = 0; pi.scale() <= zecimale; x++)
{
numitor1 = new BigDecimal(1 / numitor);
if(x % 2 == 0)
{
pi.add(numitor1);
}
else
{
pi.subtract(numitor1);
}
BigDecimal doi = new BigDecimal(2);
numitor = numitor + 2;
System.out.println(x);
System.out.println(pi);
}
BigDecimal patru;
patru = new BigDecimal(4);
pi.multiply(patru);
BigDecimal is immutable so the is no way to change it's value. (In the same way String does) This is why all the methods would operate on a BigDecimal return a new BigDecimal as the result
e.g.
pi = pi.add(numitor1);
The second problem is you are using a double in your calculation, defeating the whole point of using a BigDecimal.
The expression pi.scale() should be ~53 after the first iteration and won't get much higher the way ti is written. scale only tells you how many decimal places there are after the dot, not the accuracy of the solution.
You will get better performance if you calculate two expressions in a single loop.
The last problem you have is that each digit takes 10x longer to evaluate, calculating mroe than 15 digits (more than the precision you can get with double) it will take years to complete.