P-Adic square roots: Difference between revisions
Content added Content deleted
m (Corrected an error in a comment.) |
m (Improved code.) |
||
Line 685: | Line 685: | ||
List<List<Integer>> tests = List.of( List.of( 2, 497, 10496 ), |
List<List<Integer>> tests = List.of( List.of( 2, 497, 10496 ), |
||
List.of( 3, 15403, 26685 ), |
List.of( 3, 15403, 26685 ), |
||
List.of( |
List.of( 7, -19, 1 ) ); |
||
for ( List<Integer> test : tests ) { |
for ( List<Integer> test : tests ) { |
||
Line 697: | Line 697: | ||
System.out.println("The rational value is " + square.convertToRational()); |
System.out.println("The rational value is " + square.convertToRational()); |
||
System.out.println(); |
System.out.println(); |
||
} |
} |
||
} |
} |
||
Line 704: | Line 704: | ||
final class PadicSquareRoot { |
final class PadicSquareRoot { |
||
/** |
/** |
||
* Create a |
* Create a PadicSquareRoot number, with p = 'aPrime', |
||
* which is the p-adic square root of the given rational 'aNumerator' / 'aDenominator'. |
* which is the p-adic square root of the given rational 'aNumerator' / 'aDenominator'. |
||
*/ |
*/ |
||
Line 714: | Line 714: | ||
prime = aPrime; |
prime = aPrime; |
||
digits = new ArrayList<Integer>(DIGITS_SIZE); |
digits = new ArrayList<Integer>(DIGITS_SIZE); |
||
order = 0; |
order = 0; |
||
// Process rational zero |
// Process rational zero |
||
Line 731: | Line 731: | ||
aDenominator /= prime; |
aDenominator /= prime; |
||
order -= 1; |
order -= 1; |
||
} |
} |
||
if ( ( order & 1 ) != 0 ) { |
if ( ( order & 1 ) != 0 ) { |
||
throw new AssertionError( |
throw new AssertionError("Number does not have a square root in " + prime + "-adic"); |
||
aNumerator + " / " + aDenominator + " does not have a square root in " + prime + "-adic"); |
|||
} |
} |
||
order >>= 1; |
order >>= 1; |
||
⚫ | |||
⚫ | |||
⚫ | |||
if ( prime == 2 ) { |
if ( prime == 2 ) { |
||
Line 749: | Line 745: | ||
} |
} |
||
/** |
|||
* Return the additive inverse of this |
* Return the additive inverse of this PadicSquareRoot number. |
||
*/ |
*/ |
||
public PadicSquareRoot negate() { |
public PadicSquareRoot negate() { |
||
Line 764: | Line 760: | ||
/** |
/** |
||
* Return the product of this |
* Return the product of this PadicSquareRoot number and the given PadicSquareRoot number. |
||
*/ |
*/ |
||
public PadicSquareRoot multiply(PadicSquareRoot aOther) { |
public PadicSquareRoot multiply(PadicSquareRoot aOther) { |
||
Line 779: | Line 775: | ||
/** |
/** |
||
* Return a string representation of this |
* Return a string representation of this PadicSquareRoot as a rational number. |
||
*/ |
*/ |
||
public String convertToRational() { |
public String convertToRational() { |
||
Line 797: | Line 793: | ||
} |
} |
||
MathContext mathContext = new MathContext(PRECISION, RoundingMode.HALF_UP); |
final MathContext mathContext = new MathContext(PRECISION, RoundingMode.HALF_UP); |
||
final BigDecimal primeBig = BigDecimal.valueOf(prime); |
final BigDecimal primeBig = BigDecimal.valueOf(prime); |
||
final BigDecimal maximumPrimeBig = BigDecimal.valueOf(maximumPrime); |
final BigDecimal maximumPrimeBig = BigDecimal.valueOf(maximumPrime); |
||
Line 847: | Line 843: | ||
/** |
/** |
||
* Return a string representation of this |
* Return a string representation of this PadicSquareRoot number. |
||
*/ |
*/ |
||
public String toString() { |
public String toString() { |
||
List<Integer> numbers = new ArrayList<Integer>(digits); |
List<Integer> numbers = new ArrayList<Integer>(digits); |
||
⚫ | |||
padWithZeros(numbers); |
padWithZeros(numbers); |
||
⚫ | |||
String numberString = numbers.stream().map(String::valueOf).collect(Collectors.joining()); |
String numberString = numbers.stream().map(String::valueOf).collect(Collectors.joining()); |
||
StringBuilder builder = new StringBuilder(numberString); |
StringBuilder builder = new StringBuilder(numberString); |
||
if ( order >= 0 ) { |
if ( order >= 0 ) { |
||
for ( int i = 0; i < order; i++ ) { |
for ( int i = 0; i < order; i++ ) { |
||
builder.append("0"); |
builder.append("0"); |
||
⚫ | |||
} |
} |
||
Line 865: | Line 860: | ||
} else { |
} else { |
||
builder.insert(builder.length() + order, "."); |
builder.insert(builder.length() + order, "."); |
||
while ( builder.toString().endsWith("0") ) { |
|||
⚫ | |||
} |
|||
} |
} |
||
Line 873: | Line 872: | ||
/** |
/** |
||
* Create a |
* Create a PadicSquareRoot, with p = 'aPrime', directly from a list of digits. |
||
* |
* |
||
* With 'aOrder' = 0, the list [1, 2, 3, 4, 5] creates the p-adic ...54321.0 |
* With 'aOrder' = 0, the list [1, 2, 3, 4, 5] creates the p-adic ...54321.0 |
||
Line 890: | Line 889: | ||
private void squareRootEvenPrime(int aNumerator, int aDenominator) { |
private void squareRootEvenPrime(int aNumerator, int aDenominator) { |
||
if ( Math.floorMod(aNumerator * aDenominator, 8) != 1 ) { |
if ( Math.floorMod(aNumerator * aDenominator, 8) != 1 ) { |
||
throw new AssertionError( |
throw new AssertionError("Number does not have a square root in 2-adic"); |
||
} |
} |
||
Line 898: | Line 897: | ||
// Further digits |
// Further digits |
||
⚫ | |||
⚫ | |||
⚫ | |||
while ( digits.size() < DIGITS_SIZE ) { |
while ( digits.size() < DIGITS_SIZE ) { |
||
BigInteger factor = denominator.multiply(sum.multiply(sum)).subtract(numerator); |
BigInteger factor = denominator.multiply(sum.multiply(sum)).subtract(numerator); |
||
Line 929: | Line 931: | ||
if ( firstDigit == 0 ) { |
if ( firstDigit == 0 ) { |
||
throw new IllegalArgumentException( |
throw new IllegalArgumentException("Number does not have a square root in " + prime + "-adic"); |
||
aNumerator + " / " + aDenominator + " does not have a square root in " + prime + "-adic"); |
|||
} |
} |
||
Line 936: | Line 937: | ||
// Further digits |
// Further digits |
||
final BigInteger numerator = BigInteger.valueOf(aNumerator); |
|||
final BigInteger denominator = BigInteger.valueOf(aDenominator); |
|||
final BigInteger firstDigitBig = BigInteger.valueOf(firstDigit); |
final BigInteger firstDigitBig = BigInteger.valueOf(firstDigit); |
||
final BigInteger primeBig = BigInteger.valueOf(prime); |
final BigInteger primeBig = BigInteger.valueOf(prime); |
||
Line 942: | Line 945: | ||
BigInteger sum = firstDigitBig; |
BigInteger sum = firstDigitBig; |
||
for ( int i = 2; i < |
for ( int i = 2; i < DIGITS_SIZE; i++ ) { |
||
BigInteger nextSum = |
BigInteger nextSum = |
||
sum.subtract(coefficient.multiply(denominator.multiply(sum).multiply(sum).subtract(numerator))); |
sum.subtract(coefficient.multiply(denominator.multiply(sum).multiply(sum).subtract(numerator))); |
||
Line 996: | Line 999: | ||
private List<Integer> digits; |
private List<Integer> digits; |
||
private int order; |
private int order; |
||
private BigInteger numerator; |
|||
private BigInteger denominator; |
|||
private final int prime; |
private final int prime; |
||
Line 1,009: | Line 1,010: | ||
{{ out }} |
{{ out }} |
||
<pre> |
<pre> |
||
umber: 497 / 10496 in 2-adic |
|||
The two square roots are: |
The two square roots are: |
||
...0101011010110011.1101 |
...0101011010110011.1101 |
||
Line 1,023: | Line 1,024: | ||
The rational value is 15403 / 26685 |
The rational value is 15403 / 26685 |
||
Number: -19 / 1 in |
Number: -19 / 1 in 7-adic |
||
The two square roots are: |
The two square roots are: |
||
... |
...0126260226045320643.0 |
||
... |
...6540406440621346024.0 |
||
The p-adic value is ... |
The p-adic value is ...6666666666666666642.0 |
||
The rational value is -19 / 1 |
The rational value is -19 / 1 |
||
</pre> |
</pre> |