BigDecimal.movePointRight() hangs with very large numbers - java

The following program freezes, and I can't work out why.
import java.math.*;
public class BigDec {
public static BigDecimal exp(double z) {
// Find e^z = e^intPart * e^fracPart.
return new BigDecimal(Math.E).pow((int)z, MathContext.DECIMAL128).
multiply(new BigDecimal(Math.exp(z-(int)z)), MathContext.DECIMAL128);
}
public static void main(String[] args) {
// This works OK:
BigDecimal x = new BigDecimal(3E200);
System.out.println("x=" + x);
System.out.println("x.movePointRight(1)=" + x.movePointRight(1));
// This does not:
x = exp(123456789);
System.out.println("x=" + x);
System.out.println("x.movePointRight(1)=" + x.movePointRight(1)); //hangs
}
}
For the present purposes, the first method just creates a very large BigDecimal. (Details: it finds e to the power of z, even when this too large to be a double. I am pretty sure this method is correct, though the MathContexts may not be in the best places.)
I know e^123456789 is extremely big, but I really do want to use numbers like this. Any answers would be very gratefully received.

In fact it does not freeze, but the implementation of movePointRight in Oracle's VM can be extremely inefficient. It is often much faster to multiply or divide with a power of 10 instead of using the movePointRight or movePointLeft methods. In your case, using x.multiply(BigDecimal.TEN) will probably work much better.

Related

Converting a binary string to integer using a basic mathematical operator

Main:
public class Main{
public static void main(String[] args){
System.out.println(Convert.BtoI("10001"));
System.out.println(Convert.BtoI("101010101"));
}
}
Class:
public class Convert{
public static int BtoI(String num){
Integer i= Integer.parseInt(num,2);
return i;
}
}
So I was working on converters, I was struggling as I am new to java and my friend suggested using integer method, which works. However, which method would be most efficient to convert using the basic operators (e.g. logical, arithmetic etc.)
.... my friend suggested using integer method, which works.
Correct:
it works, and
it is the best way.
However, which method would be most efficient to convert using the basic operators (e.g. logical, arithmetic etc.)
If you are new to Java, you should not be obsessing over the efficiency of your code. You don't have the intuition.
You probably shouldn't optimize this it even if you are experienced. In most cases, small scale efficiencies are irrelevant, and you are better off using a profiler to validate your intuition about what is important before you start to optimize.
Even if this is a performance hotspot in your application, the Integer.parseint code has (no doubt) already been well optimized. There is little chance that you could do significantly better using "primitive" operations. (Under the hood, the methods will most likely already be doing the same thing as you would be doing.)
If you are just asking this because you are curious, take a look at the source code for the Integer class.
If you want to use basic arithmetic to convert binary numbers to integers then you can replace the BtoI() method within the class Convert with the following code.
public static int BtoI(String num){
int number = 0; // declare the number to store the result
int power = 0; // declare power variable
// loop from end to start of the binary number
for(int i = num.length()-1; i >= 0; i--)
{
// check if the number encountered is 1
/// if yes then do 2^Power and add to the result
if(num.charAt(i) == '1')
number += Math.pow(2, power);
// increment the power to use in next iteration
power++;
}
// return the number
return number;
}
Normal calculation is performed in above code to get the result. e.g.
101 => 1*2^2 + 0 + 1*2^0 = 5

Recursive function throws java.lang.StackOverflowError

I get the error java.lang.StackOverflowError when I try to run my code:
public class calc {
public static void main(String[] args){
double zahl = 847362;
System.out.println( wannawoerk(zahl) );
}
public static double wannawoerk(double zahl){
if (zahl == 1)
return 1;
else
return wannawoerk(zahl - 1) + zahl;
} }
Is there any workaround for this problem? I have to use a recursive function without for, while, etc.
Repeated subtraction of 1 from zahl will eventually give you 1. (Floating point subtraction by an integer on integers in this range is exact: you'd only get oddities above the 53rd power of 2).
Your problem is that your JVM is probably not going to allow you that many recursive calls.
A stack depth approaching one million is really not going to end well!
If you're required to use recursion, you could increase memory available for stack: java -Xss256m YourClass - sets stack to 256MB max.
In real world, you'd most probably use a while loop for this. Or, in this case, compute it right away (you don't need recursion for the thing you are computing), but I guess that's not the point.
The stack is not unlimited and Java doesn't have tail call optimisation. The simplest solution is to have the method
return zahl * (zahl + 1) / 2;
Ideally you wouldn't use double instead you would write
public static long sumUpTo(int n) {
return n * (n + 1L) / 2;
}
To make any sane optimisation you need a more realistic method.
This example of yours is very also illustrated in this comment! along with a few other very detailed explanations of this issue, why it happens and how to handle it.

Getting the inverse of a function that uses summation in Java

I have a program with one class, which looks like this.
public class Functions {
public static void main(String[] args) {
System.out.println(summationFunction(1)); //Prints 13
System.out.println(summationFunction(2)); //Prints 29
System.out.println(summationFunction(3)); //Prints 48
System.out.println(summationFunction(4)); //Prints 70
}
public static int summationFunction(int input) {
int summedNumber = 0;
int i = input;
while (i > 0) {
summedNumber += i * 3;
i--;
}
return 10 * input + (summedNumber);
}
}
So, this program will take in a given number and apply this function to it:
And this all works well (I have run the class Functions and everything prints just as it's supposed to.) BUT, I need to find the inverse of this function, and I need to be able to translate it to code; I do not know how to do this.
I basically need a function that will return values like this:
public static void main(String[] args) {
System.out.println(summationFunction(13)); //Prints 1
System.out.println(summationFunction(29)); //Prints 2
System.out.println(summationFunction(48)); //Prints 3
System.out.println(summationFunction(70)); //Prints 4
}
which, (as you can tell) is the opposite of the original function.
So to sum everything up, I need a function that will return the inverse of my original function (summationFunction), and I would like to know how I would model this or if there is a quick solution, in code.
One more thing: I know that I can have the method take an input and search for the most similar output of the original method, but I would like to see if there is a simpler way to do this which does not involve searching, thus giving a quicker output speed. And if you wish you can safely assume that the input of the inversed function will always be a number which will give an integer output, like 13, 29, 48, 70, etc...
By the way, if you are going to downvote the question, will you at least give a reason somewhere? The comments perhaps? I can not see any reason that this question is eligible for being downvoted, and a reason would help.
Wolfram Alpha to the rescue !
It tells you that this function can be written as :
1/24*(6*x+23)^2-529/24
So if you want to solve f(x)=a, you have :
x = 1/6*(sqrt(24*a+529)-23)
a = 70
# => x = 4
Note : Using Wolfram shouldn't prevent you from finding the answer on your own.
sum(something*i) is equal to something*sum(i) because something (3 in this case ) doesn't depend on i.
sum(i,i=1..n) is equal to n*(n+1)/2, and it's easy to prove (see Wikipedia)
So your function becomes 10*x+3*x*(x+1)/2
Expanded, it is :
(3 x^2)/2+(23 x)/2
You need to solve (3 x^2)/2+(23 x)/2 = 70, in other words :
(3 x^2)/2+(23 x)/2 - 70 = 0
It is a quadratic equation, with a=3/2, b=23/2 and c=-70 or c=-29 or c=....
You sum can be written like this 3*x*(x+1)/2 so you have equation 10*x + 3*x*(x+1)/2 = y you need to solve it.
Wolfram alpha tells that result will be 1/6.0 * (-23.0+sqrt(529.0+24.0 * y))

Java: multiple conversions in a single line

Hello StackOverflow community.
Im making my first steps in Java and OOP. I would like to know ¿Is there a way to convert and argument in to another type of variable, then convert it in to an object in a single line of operation?.
Thank you for your time and help.
This is the code that isnt mine, it is from a book im reading:
public class Changer {
public static void main(String[] arguments) {
if (arguments.length > 0) {
System.out.println("The original value: "
+ arguments[0]);
Float num1 = new Float(arguments[0]);
float num2 = num1.floatValue();
int num3 = (int)num2;
System.out.println("The final value: " + num3);
}
}
}
Boann Answer:
float is faster than Float. However, since this particular code executes only once, it will take no time either way. You should only worry about performance of those lines of code that run millions, billions or trillions of times in your program, or when you've benchmarked and determined that there is a real bottleneck. Anything else is wasting your time as a programmer, while saving no noticeable time in the program.

proper way to store large numbers in a variable

I would like to play around with numbers and however elementary, Ive been writing algorithms for the fibonacci sequence and a brute force path for finding prime numbers!
Im not a programmer, just a math guy.
However, a problem I run into quiet often is that a long long, double and floats often run out of room.
If I wanted to continue to work in JAVA, in what way can I create my own data type so that I dont run out of room.
Conceptually, I thought to put 3 doubles together like so,
public class run {
static double a = 0;
static double b = 0;
//static double c = 0;
static void bignumber(boolean x) {
if (x == true && a < 999999999) {
++a;
} else if (x == true && a == 999999999) {
++b;
a = 0;
}
System.out.print(b + "." + a + " \n");
}
public static void main(String[] args) {
while(true) {
bignumber(true);
}
}
}
is there a better way to do this,
I would like to one day be able to say
mydataType X = 18476997032117414743068356202001644030185493386634
10171471785774910651696711161249859337684305435744
58561606154457179405222971773252466096064694607124
96237204420222697567566873784275623895087646784409
33285157496578843415088475528298186726451339863364
93190808467199043187438128336350279547028265329780
29349161558118810498449083195450098483937752272570
52578591944993870073695755688436933812779613089230
39256969525326162082367649031603655137144791393234
7169566988069
or any other number found on this site
I have also tried
package main;
import java.math.BigInteger;
public class run {
BigDecimal a = 184769970321174147430683562020019566988069;
public static void main(String[] args) {
}
}
But it still seems to be out of range
Use BigDecimal (instead of double), and BigInteger (instead of int, long) for that purpose, But you can only work with them by their methods. No operators, can be used.
Used like this:
BigInteger big = new BigInteger("4019832895734985478385764387592") // Strings...
big.add(new BigInteger("452872468924972568924762458767527");
Same with BigDecimal
BigDecimal is the class used in java where you need to represent very large or very small numbers, and maintain precision. The drawbacks are that it is not a primitive, so you can't use the normal math operators (+/-/*/etc), and that it can be a little processor/memory intensive.
You can store large numbers like this:
length
digits[]
and implement your math for them. This is not very complicated. As a hint, to make everything more simple you can store the digits in reverse order. This will make your math simpler to implement - you always add nr[k] with nr[k] and have room for transport for any length numbers, just remember to fill with 0 the shorter one.
In Knuth Seminumeric Algorithms book you can find a very nice implementation for all operations.

Categories

Resources