Hi i want to calculate
2^(256bit number)
in java, but biginteger's pow function just can handle ints.
How can i calculate with larger numbers?
Is there any library?
i want to calculate all numbers from
2^0
2^1
2^2
...
2^(10^77)
I suspect the reason they didn't bother including anything like this is that in most cases, the number would be too big to represent.
Consider 2^(256 bit number). The result has (256bit number) bits, meaning that it takes more memory then there are particles in the universe.
So you'll have to find a different way to represent your logic. Perhaps you could do it symbolically.
It would be possible to do 2^(2^32) and exponents close to that, but this was probably seen as a niche case that they just didn't bother adding a function for.
Related
I try to send sensor data continuously from a stm32wb55 to my own android app.
I receive two bytes from a acceleration sensor and convert those correctly on my stm32wb55 to a float with format (XX.XXXXX, float can be negative).
Now I want to send exactly this float to my own android app.
Before, I have send two bytes from type "int or uint" to my android app and tried to convert those the same way I have done already on the stm32wb55. But the values on my screen are up to 50% of cases false. So now I try to send the float value directly, so that no more conversion on my phone is needed.
EDIT: After your contributions, I have forget my poor idea to send a float to my android app. I tried again to send the two byte integers and convert those the right way on my app. Now it works how it should. I have found the solution I needed on this post:2 Chars to Short in C.
By combining the two bytes to a 16-Bit Integer, I just needed 0x00ff & for my LSB like it be used in the answer of the referenced post.
to a float with format (XX.XXXXX, float can be negative).
This is impossible.
floats are a 32-bit IEEE754 floating point number. They do not work like you (apparently) think they do.
Specifically, they are binary constructs with a mantissa system. I'll try to explain why it doesn't work like you think they do: What is 1/3, in decimal? You'll find that you can't write it in decimal no matter how many 'bits' (digits) you use. You'll never quite get it. There's always another 3 to add.
floating point works the same way, but it's in binary (base 2) and not decimal (base 10). That means there are numbers that work great in decimal (such as 1/10th which in decimal is 0.1, with perfect accuracy) but which are like 1/3 in binary: No matter how many bits you use, you'll never get it.
Here's another way to think about it: 32-bit, so, there are only 2^32 (about 4 billion) different values. In other words, of all the numbers in existence (and there is an infinite infinity of them: There are infinite numbers, and within any 2 consecutive numbers, another infinity of numbers), only at most 4 billion are blessed: 4 billion of all numbers in existence are representable by a float value. If you try to represent a number that isn't blessed with a float, then java / your CPU will just round it to the nearest blessed number and gives you no real opportunity to deal with the error (after all, how would you represent the error? It is rather unlikely to be blessed, either).
Thus, say, '12.34567'? That's not a blessed number - therefore, your float cannot possibly represent that. It'll instead be a number very close to it, and probably a number that would round to 12.34567 if you round it to 5 digits.
send exactly this float to my own android app.
So, no, you don't want to do that. You want to send 12.34567 to your android app, not the 32 bits that represent it. Unless you intend for the android side of the app to do the rounding, which you probably should. Note that I bet there are numbers that fit the 'XX.YYYYY' pattern that just do not 'work' as a float (they round such that you're off by 1). If that's a problem, don't use floats (use doubles where I doubt that you'll find an XX.YYYYY that doesn't have a blessed number such that it rounds correctly due to having more bits to work with, or use a string, or use 2 ints, or use a single int, and have an agreement that both sides know that the int 1234567 represents 12.34567).
That last one sounds like the most convenient trick for you here, but it's hard to tell as you haven't provided much detail.
Something like (but note that the float may be off by 1 or so!):
sender side:
double v = theFloat; // doubles have less error
int z = (int) (v * 100000);
sendToPhone(z);
receiver side:
int z = getFromDevice();
double v = z;
v /= 100000;
float theFloat = (float) v;
The above will end up automatically rounding off (rounding down for positive numbers and up for negative numbers) any digits after the floating point beyond the 5 you want), and can deal with numbers up to plus or minus 21473.99999. Sounds like that'll easily cover your needs.
NB: You'll have to write the 'multiply by 100000 and then convert to an int32' code for your stm32wb55, the above is how you'd write it if the stm32wb55 was programmed in java, which I would assume it isn't. The 'go to double before multiplying by 100000 is a probably irrelevant optimization, I wouldn't be too worried if you can't do that. Note that CPUs are not guaranteed to use the exact same IEEE754 representation for floats/doubles that java does, which is why you should definitely not attempt to send the value as a float/double across the bluetooth channel, but as something universally agreed upon, such as 'a 2's complement 32-bit integer value'.
A question of mine was recently closed as a duplicate, but that didn't help me completely. My new and a more specific question is:
Can all values(whole numbers, without any decimal part) smaller than 1.7e308 and greater than 0 be stored in a double data type, as 1.7e308 is the maximum value of a double data type? Because I don't want a decimal numeral, but a large, non-decimal number so large that can't be represented even by long long.
Can all whole numbers smaller than 1.7e308 and greater than 0 be stored in a double data type
The simple answer is No.
There are various ways to come to this conclusion, but here is one that doesn't even depend on an understanding of floating point number formats.
We know that double is a 64 bit representation.
Therefore, there can be at most 264 distinct double values: that is about 1.8 x 1019
You are asking if a double can represent all integers between zero and 1.7 x 10308.
That is 1.7 x 10308 distinct values.
1.7 x 10308 is greater than 1.8 x 1019.
Therefore what you are asking is impossible.
Your best simple option is to use BigInteger.
But you said this:
... but due to slow operations on BigIntegers, I'm keeping it a last choice. It takes about a second to multiply two 4-digit numbers.
That is simply not true. If you have come to that conclusion by benchmarking, then there is something very wrong with your methodology.
Multiplying 2 x 4 digit numbers using BigInteger should take less than a microsecond.
All floating type numbers (halfs/floats/doubles/long doubles/etc) are composed of a mantissa and an exponent.
Suppose you have 1.7e308, 1.7 is the mantissa while 308 is the exponent. You can't exactly separate the two in a float. This is because every float is represented as a composition of the aforementioned in memory. Hence you can't have a "non-decimal" float.
I have a problem in calculating the power of very big exponent. That is: i enter my password :"abc" then calculate x=Hash(password). after that, i have to calculate Y = pow(g,x) in which, g is a random number. So how can i calculate Y. Any suggestion ? thank you very much !
In cryptography c = m^e (mod n) where c is the cipher text, n is your max value that can be represented. Modulus operation is needed.
In addition to that, for large numbers exponentiation Exponentiation by squaring is used. pow operation implements this algorithm. Code is here.
Cryptography implementation is much more complex, through, predefined byte arrays and byte operations. You can refer to this paper's, Modular Exponentiation and Roots section.
For your purpose, you may want to look into BigInteger.modPow() method, more relevant than Math.pow() method.
http://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html
The problem is that 10^100 is 100 digits. If your hash, lets say 4 billions, resulting value would consume 4Gb of memory. So your problem is barely solvable on a modern hardware.
Are you sure Y is pow(g,x) and not pow(g,x) mod SOME_VALUE? Then it'll make more sense.
Is there a simple way that i can manipulate high precision decimal numbers in java, without a limit on the number of decimal places, and the ability to output the number in a println or write it to a file? I want to work with one of the identities of PI that involves a sum of fractions, where k starts at 0 and goes to infinity. I know that most systems use limited decimals, but couldn't i use some pre-designed class which stores the value as a linked list of massive memory blocks if the number gets long enough? Please keep in mind i do need to do arithmetic with this class as well. Addition, subtraction, multiplication, and division should be sufficient.
I believe that you are looking for the java.lang.BigDecimal class.
Look at java.lang.BigDecimal, may solve your problem.
http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html
I couldn't really come up with a proper title for my question but allow me to present my case; I want to calculate a significance ratio in the form: p = 1 - X / Y
Here X comes from an iterative process; the process takes a large number of steps and counts how many different ways the process can end up in different states (stored in a HashMap). Once the iteration is over, I select a number of states and sum their values. It's hard to tell how large these numbers are so I am intending to implement the sum as BigInteger.
Y, on the other hand comes from a binomial coefficient with numbers in thousands-scale. I am inclined to use logGamma to calculate these coefficients, which as a result give me the natural logarithm of the value.
What I am interested in is to do division X / Y in the best/most effective way. If I can get X in the natural logarithm then I could subtract the powers and have my result as 1 - e ^ (lnX - lnY).
I see that BigInteger can't be logarithmized by Math.log, what can I do in this case?
You may be able to use doubles. A double can be extremely large, about 1.7e308. What it lacks is precision: it only supports about 15 digits. But if you can live with 15 digits of precision (in other words, if you don't care about the difference between 1,000,000,000,000,000 and 1,000,000,000,000,001) then doubles might get you close enough.
If you are calculating binomial coefficients on numbers in the thousands, then Doubles will not be good enough.
Instead I would be inclined to call the toString method on the number, and compute the log as log(10) * number.toString().length() + log(asFloat("0." + number.toString()) where asFloat takes a string representation of a number and converts it to a float.
If you need maximum precision, how about converting the BigIntegers into BigDecimals and doing algebra on them. If precision isn't paramount, then perhaps you can convert your BigIntegers into doubles and do simple algebra with them. Perhaps you can tell us more about your problem domain and why you feel logarithms are the best way to go.