The same formula gives different answers to 2296 and 1500, when the expected answer in both cases is 100. Please explain this behavior. I'm quite surprised by this simple thing. Initially I thought this must be due to operator precedence but I cannot understand this.
program with 2296 :
public class testpercent {
public static void main(String args[]) {
System.out.println("first formula ===>"+(2296 * 100 )/2296);
System.out.println("alternate formula =====>" + (2296/(2296/100)));
}
}
output:
first formula ===>100
alternate formula =====>104
same program with 1500:
public class testpercent {
public static void main(String args[]) {
System.out.println("first formula for ===>"+(1500 * 100 )/1500);
System.out.println("alternate formula for =====>" + (1500/(1500/100)));
}
}
output:
first formula ===>100
alternate formula =====>100
Program with 2296 first does (2296/100) giving 22.96 and drops the remainder of 96. Then does 2296/22 giving 104.
Program with 1500 just does the same but has no remainder and ends up with the "correct" answer.
If you want to get the output right using the alternate formula try using data types like double or float.
Related
Can anyone tell me how I can write java code for the average of the variables in case the input has a different number of variables each time?I assume that the elementary case of the problem can be solved with the help of a for loop and as long as a loop without reaching arrays.
What about something like that ?
public class Average {
public static void main(String... arguments) {
double average = Stream.of(arguments)
.mapToDouble(Double::parseDouble)
.average()
.orElse(0d);
System.out.println(average);
}
}
Exemple usage:
$ java Average 5 6 10 15 57
18.6
I am fairly new to Java and taking a course but cannot figure out this small syntax error that I keep on getting. I have been researching and staring at the problem for a while now and just cannot figure it out. I am not asking for someone to complete the project just need help with this 1 error. Sorry if I am not posting in the right section. Below is the code....
import java.util.*;
public class SolveEqu {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
double arr[]=new double[3]; //passing array as parameter
System.out.println("Enter the three coefficients of the equation separated by spaces");
for(int i=0;i<3;i++)
arr[i]=sc.nextDouble();
double result[]=solveQuadratic(arr); // unknown
//if result is negative
if(result.length==1) {
System.out.println("The equation has no real roots");
}
//if result is = to zero
else if(result.length==2) {
System.out.println(" The equation has just one real root");
System.out.format("The root is %.2f",result[1]);
}
//if result is positive
else
{
System.out.println("The equation has two real roots");
System.out.format("The root are %.2f and %.2f",result[1],result[2]);
}
}
public static double[] solveQuadratic(double[] eqn) { // method heading from assignment
double discriminant=eqn[1]eqn[1]-(4eqn[0]eqn[2]); // discriminant of the quadratic equation
if(discriminant>0) { // discriminant is positive and has 2 real roots
double r1=(-eqn[1]+Math.sqrt(discriminant))/(2eqn[0]); // equation for square roots
double r2=(-eqn[1]-Math.sqrt(discriminant))/(2eqn[0]); //equation for square roots
double res[]= {2,r1,r2};
return res;
}
else if(discriminant==0) //equal to zero the equation has just one real root
{
double r1=(-eqn[1])/(2eqn[0]);
double res[]= {1,r1};
return res;
}
else // the equation has no real roots
{
double res[]= {0}; //unknown
return res; //unknown
}
}
}
The line that is causing me trouble and throwing errors on is the following ...
double discriminant=eqn[1]eqn[1]-(4eqn[0]eqn[2]);
It says "Invalid float literal number" and "Syntax error on taken "eqn", delete this token"
Could someone help explain what this error means?
The comment by #f1sh was the first of multiple examples of the same problem.
As pointed out, you needed a multiplication operator for eqn[1]*eqn[1].
For 4eqn[0]eqn[2], the same applies. If I remember my quadratics, you are trying to multiply there, so you need 4*eqn[0]*eqn[2]. The line should read:
double discriminant=eqn[1]*eqn[1]-(4*eqn[0]*eqn[2]);
Similarly, in your calculation for r1 and r2, 2eqn[0] should be 2*eqn[0]. That fix is needed in both places you calculate r1.
So, the basic rule is that, in java, you must specify the operator between two symbols. Unlike in math, writing them next to one another does not imply multiplication.
I tried to write code to get the largest prime factor of a big number (in this case, 600851475143).
After writing four different methods (2 to show results, and 2 with other calculations), I have written the program class, and tried to run it.
When I run it, the result should appear in the console, but nothing shows up. I tried to make the variable that should be printed public, and just print it manually, but it didn't work. Eventually, I wrote the simplest System.out.print() command in the main method, but nothing appeared in the console.
I have no idea what the problem is. Does anyone here have a clue?
The class:
public class Problem3 {
public float sum1;
public float sum2;
private float num = 600851475143f;
public void methodGuy(){
while(sum1==0){
for(int i=2; i<num/2; i++){
if(num%i==0){
sum1=num/i;
} else {}
}
}
}
public void show1(){
System.out.println("the result of Guys method is: " + sum1);
}
public void methodOr(){
for(int i=2; i<num/2; i++){
for(float x=num/2; x>2; x=x-1){
if(i*x==num){
sum2=x;
}
}
}
}
public void show2(){
System.out.println("the result of Ors method is: " + sum2);
}
}
The program class:
public class Program {
public static void main(String[] args) {
Problem3 x = new Problem3();
x.methodGuy();
x.show1();
x.methodOr();
x.show2();
}
}
methodGuy will never terminate because int's can't get that big.
The largest possible value of an int is 2147483647. If your int is that number, and you add one to it, the number will wrap around and become negative. So after i++, the next value will be -2147483648. Since the loop will continue as long as i is less than 600851475143/2 = 300425237071.5, and since i will always be less than that, your loop is infinite.
Best would be to make both i and num have type long, instead of int or float. Even if you do that, your loop will probably run for a very long time.
In fact, if there are no factors, the loop will be infinite, because sum will never be set to something other than 0, and then since you say while (sum==0), the loop will just start over again and do the same thing infinitely. So aside from the wraparound problem, your algorithm still needs work.
Further note: You definitely do not want to use float for this, because the number 600851475143 cannot be represented exactly. The actual value of num will be 600851480576.
I am creating a small game for students, and in a place, it has to display the value of 27830457+1
I can call BigInteger's pow() method if the number is not this much big. Since the number is very big, that method is useless. How can I find the HUGE power of this kind of numbers? Please help!
Well in binary it's just 10000...01 with 7830456 zeros.
In decimal, there will be approximately two million digits, which is about 2 megabytes of storage. This is well within the feasibility of BigInteger with a default heap size.
In practice, it even uses exponentiation by squaring to compute it quickly (though not guaranteed by the specifications). However the conversion to a String will take some time since it's a linear time operation.
import java.math.BigInteger;
public class BigPow {
public static void main(String[] args) {
BigInteger result = (new BigInteger("2")).pow(27830457).add(BigInteger.ONE);
System.out.println(result);
}
}
Here's a version which will print out the digits slowly:
import java.math.BigInteger;
public class BigPow {
public static void main(String[] args) {
BigInteger result = (new BigInteger("2")).pow(27830457).add(BigInteger.ONE);
BigInteger powten = BigInteger.TEN.pow(2357202);
while(powten.compareTo(BigInteger.TEN) > 0) {
BigInteger digit = result.divide(powten).mod(BigInteger.TEN);
System.out.print(digit);
powten = powten.divide(BigInteger.TEN);
}
}
}
The first digits are:
27337386390628313557307248857732033008168556429738078791761607160549944954510637855005417718646965163546351365984857761796847950377880836291434244529029919271706271982523405687134334692691344477538489450971091437463160940371624647030064741968436401566711255284353690448270545402444641547030399228243743315193608710148721648879085592699913299745785392609301774185427367430782834290629265859073814466687714408436025809860462926275610087354595992436000187216152954542774991509992374985538879880897902639600451627914923043483436514419544413306391278529303650112773297502090619459167888563274071587848623085880067091968911236296732119252937497152769541579516150659424997041968213122450568364121976474269097910635641227922923398092242409755554115985855831015459204780391470591543281267373716556272259386683864538263922398723602210173800151405332100275913619559563575829498369806957031526077258236305186254269056811134135133350936924294101345294335698866339561918857584229744277901180792029180156485000086528174400878657004645726892816943589969701053158760210512171516969813345080894134663207988962182426459128577282934948790911691329475034324656384238413230485050607666988301932660490870167246016897007835866691705399794247746213819662270451531049826029606671683482160663572103374
Confirmed by WolframAlpha.
I don't know why you think BigInteger isn't up to this:
import java.math.BigInteger;
public class Test {
public static void main(String[] args) throws Exception {
BigInteger big = BigInteger.valueOf(2)
.pow(7830457)
.add(BigInteger.ONE);
System.out.println(big);
}
}
It takes a little while (particularly the string conversion at the end), but it's perfectly reasonable.
As Peter noted, shifting ONE left 7830457 is much neater, mind you. I'd argue it's a bit less clear - and of course it doesn't help in the string conversion part.
EDIT: Almost all of the time is spent in the string conversion. It finished in the end on my box though. I can't see the start of it any more, but it ends with...
08570502260645006898157834607641626568029302766491883299164453304032280181734737
79366998940913082443120328458954436211937775477966920836932628607888755839700303
873
You should be able to calculate this with BigInteger.
System.out.println(BigInteger.ONE.shiftLeft(7830457).add(BigInteger.ONE));
Try something like this:
BigInteger mant = new BigInteger("2");
BigInteger result = mant.pow(7830457).add(BigInteger.ONE);
In my app, I handle numbers as BigDecimal and store them as NUMBER(15,5). Now I'd need to properly check on Java if the BigDecimal values would fit the column, so that I can generate proper error messages without executing the SQL, catching exceptions and verifying the vendor error code. My database is Oracle 10.3, and such errors cause error 1438.
After some googling, I found no such code for that, so I came up with my own. But I'm really unsatisfied with this code... simple, but at the same time simple enough to doubt its correctness. I tested it with many values, random ones and boundaries, and it seems to work. But as I'm really bad with numbers, I'd like some more robust and well-tested code.
//no constants for easier reading
public boolean testBigDecimal(BigDecimal value) {
if (value.scale() > 5)
return false;
else if (value.precision() - value.scale() > 15 - 5)
return false;
else
return true;
}
Edit: Recent tests did not got an exception for numbers out of scale, just got silently rounded, and I'm not sure what is different between not and when I made these first tests. Such rounding is unacceptable because the application is financial, and any rounding/truncation must be explicit (through BigDecimal methods). Exception-is-gone aside, this test method must assure that the number is not too large for the desired precision, even if by non-significant digits. Sorry about the late clarification.
Thanks for your time.
I'm still curious about this question. My code is still running, and I haven't got some "proof" of correctness or fail situation, or some standard code for this kind of test.
So, I'm putting a bounty on it, hopefully getting any of these.
The following regexp would do the trick too:
public class Big {
private static final Pattern p = Pattern.compile("[0-9]{0,10}(\\.[0-9]{0,5}){0,1}");
public static void main(String[] args) {
BigDecimal b = new BigDecimal("123123.12321");
Matcher m = p.matcher(b.toString());
System.out.println(b.toString() + " is valid = " + m.matches());
}
}
This could be another way to test your code or it could be the code. The regexp requires between 0 and 10 digits optionally followed by a decimal point and 0 to 5 more digits. I didn't know if a sign was needed or not, as I think about it. Tacking something like [+-]{0,1} to the front will do.
Here is a better class, maybe, and a test class with a partial set of tests.
public class Big {
private static final Pattern p = Pattern.compile("[0-9]{0,10}(\\.[0-9]{0,5}){0,1}");
public static boolean isValid(String s) {
BigDecimal b = new BigDecimal(s);
Matcher m = p.matcher(b.toPlainString());
return m.matches();
}
}
package thop;
import junit.framework.TestCase;
/**
* Created by IntelliJ IDEA.
* User: tonyennis
* Date: Sep 22, 2010
* Time: 6:01:15 PM
* To change this template use File | Settings | File Templates.
*/
public class BigTest extends TestCase {
public void testZero1() {
assertTrue(Big.isValid("0"));
}
public void testZero2() {
assertTrue(Big.isValid("0."));
}
public void testZero3() {
assertTrue(Big.isValid("0.0"));
}
public void testZero4() {
assertTrue(Big.isValid(".0"));
}
public void testTooMuchLeftSide() {
assertFalse(Big.isValid("12345678901.0"));
}
public void testMaxLeftSide() {
assertTrue(Big.isValid("1234567890.0"));
}
public void testMaxLeftSide2() {
assertTrue(Big.isValid("000001234567890.0"));
}
public void testTooMuchScale() {
assertFalse(Big.isValid("0.123456"));
}
public void testScientificNotation1() {
assertTrue(Big.isValid("123.45e-1"));
}
public void testScientificNotation2() {
assertTrue(Big.isValid("12e4"));
}
}
one of the problems with your function is that in some cases it may be too restrictive, consider:
BigDecimal a = new BigDecimal("0.000005"); /* scale 6 */
a = a.multiply(new BigDecimal("2")); /* 0.000010 */
return testBigDecimal(a); /* returns false */
As you can see, the scale is not adjusted down. I can't test right now if something similar happens with high-end precision (1e11/2).
I would suggest a more direct route:
public boolean testBigDecimal(BigDecimal value) {
BigDecimal sqlScale = new BigDecimal(100000);
BigDecimal sqlPrecision = new BigDecimal("10000000000");
/* check that value * 1e5 is an integer */
if (value.multiply(sqlScale)
.compareTo(value.multiply(sqlScale)
.setScale(0,BigDecimal.ROUND_UP)) != 0)
return false;
/* check that |value| < 1e10 */
else if (value.abs().compareTo(sqlPrecision) >= 0)
return false;
else
return true;
}
Update
You've asked in a comment if the database would throw an error if we try to insert 0.000010. In fact the database will never throw an error if you try to insert a value with too much precision, it will silently round the inserted value.
The first check is therefore not needed to avoid an Oracle error, I was assuming that you were performing this test to make sure that the value you want to insert is equal to the value you actually inserted. Since 0.000010 and 0.00001 are equal (with BigDecimal.compareTo) shouldn't they both return the same result?
Instead if looping over thousands of random numbers, you could write test cases that stress the 'edges' - the maximum value +.00001, the maximum value, the maximum value - .00001, 0, null, the minimum value -.00001, the minimum value, the minimum value + .00001, and values with 4, 5, and 6 values to the right of the decimal point. There are probably many more.
If you have those in junit, you're good.
Well, since nobody came up with another solution, I'm leaving the code as it is.
I couldn't make this precision/scale test fail, and it always matched the regex solution, so maybe both are correct (I tested the boundaries and with over 5M randomly generated values). I'll use the precision/scale solution, as it is over 85% faster, and may it fail I replace it.
Thanks for your replies Tony.
My previous "answer", still here for history purposes, but I'm looking for a real answer =)