Double precision values - java

Just a day before I participated in the qualification round of Google Code Jam. This is my first experience of such an online coding contest. It was really fun.
There were three problems given of which i was able to solve two. But on one of the problems I was asked to work with values that are really huge. I am a Java guy and I thought I would go for double variable. Unfortunately, the precision of double also was not enough. Moreover, I attended this during the closing stage, I was not having the time to dig much into it (plus solving 1 is enough to qualify to the next stage).
My question is this, How to have a precision mechanism that is greater than double. My coding experience is in Java, so it would be great if you could please answer in that lines.
Thanks

Java has BigDecimall for arbitrary-precision arithmetic - but it's much, much slower than using double.
It's also possible that the problem in question was supposed to be soved by using algebraic transformations and e.g. work with logarithms.

If the problem requires integers you can use BigInteger.
Also, long is slightly better than double for integers, with 63 bits compared to 53 bits of precision (assuming positive numbers).

You can use arbitrary precision numbers, such as BigDecimal - it's slower but as precise as you specify.

Related

golden ratio calculation with precision

I've got the task to calculate the golden ratio (phi = (1+ sqrt(5))/2).
But I need to calculate it with about 50 decimal digits / decimal places and then round the result up to 30 decimal digits and print it on the console. I am allowed to use BigDecimal and MathContext.
Does anyone have an idea how to calculate it? I am lost right now.
Thanks
I won't try to solve your problem for you!
However I think to point you in a promising direction would be to look at the API:
https://docs.oracle.com/javase/9/docs/api/java/math/BigDecimal.html
and specifically at the constructor:
BigDecimal(BigInteger unscaledVal, int scale, MathContext mc)
I believe that if you experiment with these objects you can meet your goal.
Note: sqrt was only added to BigDecimal in Java 9.
Good luck.
I found this on the web. It can be used to verify your calculations.
String goldenRatio =
"1.61803398874989484820458683436563811772030917980576286213544862270526046281890" +
"244970720720418939113748475408807538689175212663386222353693179318006076672635";
You can verify the correctness of a regular calculation by
Verifying the length (don't forget the decimal point and the whole number digits).
verifying that it matches some initial part of the supplied answer.
To calculate normally, I used MathContext of precision = 30 and RoundingMode.HALF_UP.
This may not work for the way you are expected to do it. If you run into problems, folks here will be able to help.
I strongly suggest you post an attempt before asking for any additional help though.

what is the significance of modulo 10^9+7 used in codechef and spoj problems?

I was working on a problem which requires output as "For each line output the answer modulo 10^9+7". Why is modulo 10^9+7 included in the problem? What is its significance?
I'm not looking for a solution to the problem; only the significance of that particular constant.
Problems ask for results modulo primes because the alternatives, namely asking for a floating-point result giving the "high-order bits" and asking for the whole result, aren't always what the problem setter is looking for.
These problems are often "find and implement a recurrence" problems. The low-order bits will often tell you whether the recurrence you found is right.
There may be a special trick for the "high-order bits" problem, perhaps based on a clever analytic approximation.
The reason people don't often ask for the whole result is that this requires the contestant to implement big-number arithmetic.
Problem setters usually don't want unexpected tricks to crack their problems for "the wrong reasons."
10^9+7 winds up being a pretty good choice of prime. It is a "safe prime." What that means:
10^9+7 is a prime number. This means that the "Chinese remainder trick" doesn't apply; if you're trying to work something out modulo a product of two primes, say pq, then you can work it out modulo p and modulo q and use the extended Euclidean algorithm to put the pieces together.
More than that, 10^9+6, which is 10^9+7-1, is twice a prime. So the multiplicative group modulo 10^9+7 doesn't decompose into small things and hence no Chinese-remainder-like trick applies there.
In some problems the answers are very big numbers, but forcing you to implement long arighmetics is not the purpose of the problem authors. Therefore they ask you to calculate answer modulo some number, like 1000000007, so you don't have to implement long arithmetics, but the answer is still verifiable.
If it was asked to give answer as modulo 10^9 you could mask the bits easily but to make problems more tough a number such as 10^9+7 is choosen

Take Power of Decimal to Maximum Precision

I want to do the following in java:
Math.pow((int),(double))
and keep the decimal precision to more than 16 (much greater than that actually).
Is this possible? I know it involves using BigDecimal and maybe ln functions, but I'm not sure how to approach this.
Thanks in advance.
EDIT
The reason I am asking is because I am trying to compute pi to an enormous amount of precision. Currently, I am using Chudnovsky's algorithm. I've tried to use taylor series for this purpose and it takes much too long to be practical.
EDIT
Maybe this is a better question: How do you find the square root of a BigDecimal. (Technically, same as the original since raising to the .5 is...)

Java - computing large mathematical expressions

Im facing a scenario where in ill have to compute some huge math expressions. The expressions in themselves are simple, ie have just the conventional BODMAS fundamental but the numbers that occur as operands are very large, to the tune of 1000 digit numbers. I do know of the BigInteger class of the java.math module but am looking for a different way so that the computation can occur also in a speedy manner. Im a guy still finding his feet in Java, so any pointers or advice in gthis regard would be of great help.
Regards
p1nG
Try it with BigInteger, profile the results with some test calculations, and see if it will work for you, before you look for something more optimized.
Since you say you are new to Java, I would have to suggest you use BigInteger and BigDecimal unless you want to write your own arbitrarily large number handlers. BigInteger and BigDecimal are fast enough for most uses of them. The only time I've had speed issues with them is when dealing with numbers on the order of a million digits.
That is unless you have a specific need for not using BigInteger.
First write the program correctly (using BigFoo) and then determine if optimization is appropriate.
BigInteger/BigFloat will be the most optimized implementation of generalized math that you will possibly get.
If you want it faster, you MIGHT be able to write assembly to use bit-shifting patters for specialized math (well, like divide by 2 tends to be a simple right shift), but if you are doing more than a few different types of equations, that will be very impractical.
BigInteger is only slow in comparison to int, but it will probably be the best you are going to possibly get for operations on numbers of more than 64 bits or so without going to another language--and even then you probably won't get much of an improvement unless that other language is assembly...
I am surprised that equations with 1000 digits have a practical application (except perhaps encryption)
Could you could explain what you are doing and what your speed requirements are?

Using the right numeric data type

After becoming more engaged with training new engineers as well as reading Jon Skeet's DevDays presentation I have begun to recognize many engineers aren't clear when to use which numeric datatypes when. I appreciate the role a formal computer science degree plays in helping with this, but I see a lot of new engineers showing uncertainty because they have never worked with large data sets, or financial software, or programming phyiscs or statistics problems, or complex datastore issues.
My experience is that people really grok concepts when they are explained within context. I am looking for good examples of real programming problems where certain data is best represented using data type. Try to stay away from the textbook examples if possible. I am tagging this with Java, but feel free to give examples in other languages and retag:
Integer, Long, Double, Float, BigInteger, etc...
I really don't think you need examples or anything complex. This is simple:
Is it a whole number?
Can it be > 2^63? BigInteger
Can it be > 2^31? long
Otherwise int
Is it a decimal number?
Is an approximate value ok?
double
Does it need to be exact? (example: monetary amounts!)
BigDecimal
(When I say ">", I mean "greater in absolute value", of course.)
I've never used a byte or char to represent a number, and I've never used a short, period. That's in 12 years of Java programming. Float? Meh. If you have a huge array and you are having memory problems, I guess.
Note that BigDecimal is somewhat misnamed; your values do not have to be large at all to need it.
BigDecimal is the best when it comes to maintaining accurate floating point calculations, and being able to specify the desired accuracy. I believe float (and to some extent double) offer performance benefits over BigDecimal, but at the cost of accuracy and usability.
One important point you might want to articulate is that it's almost always an error to compare floating-point numbers for equality. For example, the following code is very likely to fail:
double euros = convertToEuros(item.getCostInDollars());
if (euros == 10.0) {
// this line will most likely never be reached
}
This is one of many reasons why you want to use discrete numbers to represent currency.
When you absolutely must compare floating-point numbers, you can only do so approximately; something to the extent of:
double euros = convertToEuros(item.getCostInDollars());
if (Math.abs(euros - 10.0) < EPSILON) {
// this might work
}
As for practical examples, my usual rule of thumb is something like this:
double: think long and hard before using it; is the pain worth it ?
float: don't use it
byte: most often used as byte[] to represent some raw binary data
int: this is your best friend; use it to represent most stuff
long: use this for timestamps and database IDs
BigDecimal and BigInteger: if you know about these, chances are you know what you're doing already, so you don't need my advice
I realize that these aren't terribly scientific rules of thumb, but if your target audience are not computer scientists, it might be best to stick to basics.
normally numeric if we're talking machine independenat (32/64bit) data type size are as below,
integer: 4 bytes
long: 8 bytes
decimal/float: 4bytes
double : 8bytes
and the sizes reduced to half for signed values (eg: for 4bytes, unsigned=4billions, signed=2billions)
bigInt (depends on language implementation) sometimes up to 10bytes.
for high volumes data archiving (such as search engine) i would highly recommended byte and short to save spaces.
byte: 1 byte, (0-256 unsigned, -128 - 128 signed)
short: 2 byte (65k unsigned)
let's say you want to save record about AGE, since nobody ever lives over 150, so you used data type BYTE (read above for size) but if you use INTEGER you already wasted extra 3bytes and seriously tell me wth live over 4billions yrs.
VInt's in Lucene are the devil. The small benefit in size is outweighed hugely by the performance penalty in reading them byte-by-byte.
A good thing to talk about is the space versus time trade off. Saving 200mb was great in 1996, but in 2010, thrashing IO buffers reading a byte at a time is terrible.

Categories

Resources