GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||
GeezerVison is showing www.apfloat.org — Apfloat tutorial Apfloat tutorialContents:
Classpath setting Classpath settingTo use the apfloat library, you need to add the apfloat.jar file to the classpath. Depending on the development environment this is done in different ways. In a command prompt or shell the CLASSPATH environment variable simply needs to be set to include the path to the apfloat.jar file. To run the apfloat samples, you can additionally append the samples.jar to the classpath. Similarly the calculator application can be run by appending calc.jar to the classpath. First exampleA simple example program for printing the square root of two to one thousand digits of precision is as follows: import org.apfloat.Apfloat;
import org.apfloat.ApfloatMath;
public class Test
{
public static void main(String[] args)
{
Apfloat x = new Apfloat(2, 1000);
System.out.println(ApfloatMath.sqrt(x));
}
}
Constructing ApfloatsThere are multiple ways to construct an Apfloat object. The following are some examples:
Double and float constructor caveatsIn general, it's not recommended to use any of the Apfloat constructors taking a double or float to specify the value of the number. This is because the conversion from a float or double to the apfloat internal presentation does not happen exactly. Therefore, even if you specify the number to have more precision than the default, an Apfloat constructed from a double will never be accurate to more than 16 digits and from a float more than 8 digits. So, just don't use them. Many floating-point numbers can't even be presented exactly as such in a float or double. Internally, floats and doubles are specified as an integer multiplied by a power of two (the exponent of two can be negative), as per the IEEE 754 standard for binary floating-point numbers. So, numbers that aren't powers of two multiplied by some integer can't be presented exactly as a float or double. Try the following:
Instead of printing Furthermore, this can and does happen also with numbers that can be presented exactly as floats or doubles. For example: Apfloat x = new Apfloat(0.5, 50); System.out.println(x); The above might print, not If you insist on having the exact value of a primitive Apfloats are immutableApfloats are immutable. A common mistake is to attempt something like the following: Apfloat a = new Apfloat(2); Apfloat b = new Apfloat(3); a.add(b); System.out.println(a);
If the above is supposed to add
This happens because Apfloat a = new Apfloat(2); Apfloat b = new Apfloat(3); a = a.add(b); System.out.println(a); PrecisionThe concept of precision was mentioned already earlier. Every Apfloat object has both a value and a precision. The precision affects most mathematical operations performed with the number.
The above example used the square root function, which is calculated with the method
Elementary operatorsThe behavior of precision can sometimes be unexpected even with the basic mathematical operators. The following explains the handling of precision. Multiplication and divisionThe precision of the result of a multiplication or division is the minimum of the precision of the two operands. Such a precision for multiplication makes most sense if you think about the precision for some physical measure. For example, if you have a wooden stick that is 100cm long, to an accuracy of 1cm, then the precision of the length of the stick is 3 digits. The stick could be 99cm long or 101cm long. In other words, the length of the stick is 100±1cm. Now, let's assume you have exactly 100 of such sticks (you counted every one of them). If you put all of the sticks together to make one long stick, then how long is that stick, and how accurately you know its length? To calculate the length, you must perform a multiplication of two numbers: the length of one stick (which you know to a precision of 3 digits) and the number of sticks (which you know to infinite precision, since it's an integer). The total length is then of course 10000±100cm, i.e. a number with 3 digits of precision (the minimum of 3 and ∞). On the other hand, if you just have a large bunch of these sticks, but you don't know exactly how many sticks there are, then the result has different precision. For example if you have a pile of 100 sticks, give or take 10, then you know there are 100±10 sticks, i.e. a number with only two digits of precision. If you put all of them in a row to make one long stick, then you can calculate the total length of the sticks to only two digits of precision. It's at least 100cm*90 and at most 100cm*110 i.e. 10000±1000cm, a number with two digits of precision (again, the minimum of 3 and 2). Addition and subtractionTo determine the precision of the result, the numbers are lined up just like with the elementary school addition and subtraction algorithm. Whichever number has less precision, considering the scales of the numbers (the location of the decimal point), determines the precision of the result. For example: 111.111111 // Precision of 9 digits + 22.222 // Precision of 5 digits ------------ 133.333 // The extra 3 digits of precision that the first operand has does not help; the result has only 6 digits of precision here Subtraction works in a similar fashion. With addition, if there is a carry, it can increase the precision by one digit. For example: 987.654 // Precision of 6 digits + 51.234 // Precision of 5 digits --------- 1038.888 // Because of the carry, there is one more digit of precision than what might be expected; precision is 7 digits With subtraction, if there is a loss of digits, precision can decrease significantly. For example: 111.222333 // Precision of 9 digits
- 111.222222 // Precision of 9 digits
------------
0.000111 // Most of the digits cancel out each other; the result has only 3 digits of precision left
The precision of zeroNote that a number with a value of zero always has infinite precision, no matter if you try to specify otherwise. This can cause unexpected behavior in rare cases. For example:
The above would not return π/2 to 100 digits of precision. Instead it would throw an exception, because the parameter with value zero has an infinite precision (and not 100 digits of precision as specified). The library can't calculate π/2 to infinite precision, obviously; an exception would be thrown.
If you think the above is a problem, then there are two helper classes to get around this problem: Fixed-point and floating-point outputBy default, when you convert an Apfloat to a string (e.g. for printing it), it uses a floating-point format. For example: Apfloat x = new Apfloat("0.5");
System.out.println(x);
The above does not print
To get the output of Apfloat x = new Apfloat("0.5");
System.out.println(x.toString(true));
This is often very helpful, however there are some caveats. If the exponent of the number is very large compared to the number of significant digits, the string can become very long. For example: Apfloat x = new Apfloat("1.2345e1000000");
System.out.println(x);
System.out.println(x.toString(true));
The first line outputs compactly Advanced mathematical functions
In addition to the square root, the Integers
There is a subclass of Apfloat for arbitrary-precision integers, the Apint class. Apint numbers work in much the same way as the floating-point
Apfloat numbers, except the precision of an Apint is always infinite. The Complex numbers
The superclass of Apfloat is the Apcomplex class, for arbitrary-precision complex numbers. An Apcomplex can be constructed from two
Apfloats, to define the real and imaginary parts. There is also a string constructor. Apcomplex has mostly the same methods that
Apfloat has, and the Apfloat x = new Apfloat("3.00");
Apfloat y = new Apfloat("4.00");
Apcomplex w = new Apcomplex(x, y);
Apcomplex q = new Apcomplex("(5.00,6.00)");
System.out.println(w.multiply(q).toString(true)); // Prints (-9, 38)
Rational numbers
There is also a class for arbitrary-precision rational numbers, the Aprational class. Aprationals work in much the same way as the floating-point
Apfloat numbers and Apint integers. The Using some other radix than 10
Every number has a value, precision and radix. By default radix 10 i.e. the decimal radix is used. To specify a different radix
to be used, the radix can be specified as the third argument in the Apfloat constructor (or second argument in the Apint constructor).
Only numbers with the same radix can be used in mathematical operations. To convert a number to a different radix, use the
Apfloat x = new Apfloat(1);
Apfloat y = new Apfloat("10", Apfloat.DEFAULT, 16);
System.out.println(x.add(y.toRadix(10)).toString(true));
The above should print Equality and comparison
All of the arbitrary precision number classes have
As usual with floating-point numbers, it's better to compare that two numbers are equal to each other within some margin of error.
Apfloats have a method, Apfloat a = new Apfloat(1000000, 6); Apfloat b = new Apfloat(1000005, 6); Apfloat c = new Apfloat(2000000, 6); Apfloat d = new Apfloat(2000005, 6); System.out.println(a.equals(b)); // true, equal within 6 digits of precision System.out.println(c.equals(d)); // true, equal within 6 digits of precision System.out.println(a.add(c).equals(b.add(d))); // false, not equal within 6 digits of precision System.out.println(a.equalDigits(b)); // 6 System.out.println(c.equalDigits(d)); // 6 System.out.println(a.add(c).equalDigits(b.add(d))); // 5 due to round-off error in b.add(d) Formatting
Apfloat implements the
Only the Apfloat x = ApfloatMath.pi(50).multiply(new Apfloat(100));
String.format("%s", x) // "3.1415926535897932384626433832795028841971693993751e2"
String.format("%100s", x) // " 3.1415926535897932384626433832795028841971693993751e2"
String.format("%-100s", x) // "3.1415926535897932384626433832795028841971693993751e2 "
String.format("%.10s", x) // "3.141592653e2"
String.format("%#s", x) // "314.15926535897932384626433832795028841971693993751"
String.format(Locale.GERMAN, "%s", x) // "3,1415926535897932384626433832795028841971693993751e2"
Bug reports, questions and comments should be sent to the author. Last updated: July 6th, 2019 | ||||||||||||||||||||||||||||
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |