Merge remote-tracking branch 'upstream/master'

This commit is contained in:
mcasari
2023-10-06 21:29:32 +02:00
65 changed files with 1040 additions and 104 deletions
+2
View File
@@ -1,3 +1,5 @@
## Relevant Articles
- [Sequenced Collections in Java 21](https://www.baeldung.com/java-21-sequenced-collections)
- [String Templates in Java 21](https://www.baeldung.com/java-21-string-templates)
- [Unnamed Classes and Instance Main Methods in Java 21](https://www.baeldung.com/java-21-unnamed-class-instance-main)
- [Unnamed Patterns and Variables in Java 21](https://www.baeldung.com/java-unnamed-patterns-variables)
@@ -5,3 +5,4 @@ This module contains articles about Java Character Class
### Relevant Articles:
- [Character#isAlphabetic vs. Character#isLetter](https://www.baeldung.com/java-character-isletter-isalphabetic)
- [Difference Between Javas “char” and “String”](https://www.baeldung.com/java-char-vs-string)
- [Increment Character in Java](https://www.baeldung.com/java-char-sequence)
@@ -5,4 +5,6 @@
### Relevant Articles:
- [Introduction to Roaring Bitmap](https://www.baeldung.com/java-roaring-bitmap-intro)
- [Creating Custom Iterator in Java](https://www.baeldung.com/java-creating-custom-iterator)
- [Difference Between Arrays.sort() and Collections.sort()](https://www.baeldung.com/java-arrays-collections-sort-methods)
- [Skipping the First Iteration in Java](https://www.baeldung.com/java-skip-first-iteration)
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-4)
@@ -3,4 +3,4 @@
This module contains articles about the Java ArrayList collection
### Relevant Articles:
- [Create an ArrayList with Multiple Object Types](https://www.baeldung.com/arraylist-with-multiple-object-types)
- [Create an ArrayList with Multiple Object Types](https://www.baeldung.com/java-arraylist-multiple-object-types)
@@ -3,3 +3,4 @@
This module contains articles about conversions among Collection types in Java.
### Relevant Articles:
- [Converting HashMap Values to an ArrayList in Java](https://www.baeldung.com/java-hashmap-arraylist)
@@ -12,10 +12,10 @@ public class EpochTimeToLocalDateTimeConverterUnitTest {
@Test
public void testConvertEpochTimeToLocalDateTime() {
long epochTimeMillis = 1624962431000L; // Example epoch time in milliseconds
LocalDateTime expectedDateTime = LocalDateTime.of(2021, 6, 29, 12, 13, 51);
LocalDateTime expectedDateTime = LocalDateTime.of(2021, 6, 29, 10, 27, 11);
Instant instant = Instant.ofEpochMilli(epochTimeMillis);
ZoneId zoneId = ZoneId.systemDefault();
ZoneId zoneId = ZoneId.of("UTC");
LocalDateTime actualDateTime = instant.atZone(zoneId).toLocalDateTime();
assertEquals(expectedDateTime, actualDateTime);
+1 -1
View File
@@ -3,6 +3,6 @@
This module contains articles about core Java input and output (IO)
### Relevant Articles:
- [Get File Extension From MIME Type in Java](https://www.baeldung.com/java-mime-type-file-extension)
- [[<-- Prev]](/core-java-modules/core-java-io-4)
@@ -25,8 +25,12 @@
<version>${commons-codec}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
</dependencies>
<build>
<finalName>core-java-numbers-6</finalName>
<resources>
@@ -39,5 +43,6 @@
<properties>
<commons-codec>1.15</commons-codec>
<guava.version>32.1.2-jre</guava.version>
</properties>
</project>
@@ -0,0 +1,8 @@
package com.baeldung.bigintegerroot;
public class BenchmarkRunner {
public static void main(String[] args) throws Exception {
org.openjdk.jmh.Main.main(args);
}
}
@@ -0,0 +1,10 @@
package com.baeldung.bigintegerroot;
public class BigIntegerHolder {
private BigIntegerHolder() {
}
public static final String BIG_NUMBER = "179769313000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
public static final String VERY_BIG_NUMBER = "32473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834";
public static final String INSANELY_BIG_NUMBER = "3247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834324739274923749279342847923749237492374987230480128343247392749237492793428479237492374923749872304801283432473927492374927934284792374923749237498723048012834";
}
@@ -0,0 +1,60 @@
package com.baeldung.bigintegerroot;
import static com.baeldung.bigintegerroot.BigIntegerHolder.*;
import com.baeldung.bigintegerroot.algorithms.Newton;
import com.baeldung.bigintegerroot.algorithms.NewtonPlus;
import com.google.common.math.BigIntegerMath;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;
@Warmup(iterations = 1)
@Measurement(iterations = 1, time = 1, timeUnit = TimeUnit.MINUTES)
@Fork(1)
@State(Scope.Benchmark)
public class BigIntegerSquareRootBenchmark {
@Param({BIG_NUMBER, VERY_BIG_NUMBER, INSANELY_BIG_NUMBER})
public String number;
@Benchmark
@BenchmarkMode(Mode.Throughput)
public void calculateRootWithJava(Blackhole blackhole) {
final BigInteger integer = new BigInteger(number);
final BigInteger root = integer.sqrt();
blackhole.consume(root);
}
@Benchmark
@BenchmarkMode(Mode.Throughput)
public void calculateRootWithGuava(Blackhole blackhole) {
final BigInteger integer = new BigInteger(number);
final BigInteger root = BigIntegerMath.sqrt(integer, RoundingMode.DOWN);
blackhole.consume(root);
}
@Benchmark
@BenchmarkMode(Mode.Throughput)
public void calculateRootWithNewtonPlus(Blackhole blackhole) {
final BigInteger integer = new BigInteger(number);
final BigInteger root = NewtonPlus.sqrt(integer);
blackhole.consume(root);
}
@Benchmark
@BenchmarkMode(Mode.Throughput)
public void calculateRootWithNewton(Blackhole blackhole) {
final BigInteger integer = new BigInteger(number);
final BigInteger root = Newton.sqrt(integer);
blackhole.consume(root);
}
}
@@ -0,0 +1,29 @@
package com.baeldung.bigintegerroot.algorithms;
import java.math.BigInteger;
public class Newton {
private Newton() {
}
public static BigInteger sqrt(BigInteger n) {
// Initial approximation
BigInteger x = n.divide(BigInteger.TWO);
// Tolerance level (small positive integer)
BigInteger tolerance = BigInteger.ONE;
while (true) {
// x_new = 0.5 * (x + n / x)
BigInteger xNew = x.add(n.divide(x)).divide(BigInteger.TWO);
// Check for convergence within tolerance
if (x.subtract(xNew).abs().compareTo(tolerance) <= 0) {
return xNew;
}
x = xNew;
}
}
}
@@ -0,0 +1,108 @@
package com.baeldung.bigintegerroot.algorithms;
import java.math.BigInteger;
public class NewtonPlus {
private NewtonPlus() {
}
// A fast square root by Ryan Scott White.
public static BigInteger sqrt(BigInteger x) {
if (x.compareTo(BigInteger.valueOf(144838757784765629L)) < 0) {
long xAsLong = x.longValue();
long vInt = (long)Math.sqrt(xAsLong);
if (vInt * vInt > xAsLong)
vInt--;
return BigInteger.valueOf(vInt); }
double xAsDub = x.doubleValue();
BigInteger val;
if (xAsDub < 2.1267e37) // 2.12e37 largest here
// since sqrt(long.max*long.max) > long.max
{
long vInt = (long)Math.sqrt(xAsDub);
val = BigInteger.valueOf
((vInt + x.divide(BigInteger.valueOf(vInt)).longValue()) >> 1);
}
else if (xAsDub < 4.3322e127) {
// Convert a double to a BigInteger
long bits = Double.doubleToLongBits(Math.sqrt(xAsDub));
int exp = ((int) (bits >> 52) & 0x7ff) - 1075;
val = BigInteger.valueOf((bits & ((1L << 52)) - 1) | (1L << 52)).shiftLeft(exp);
val = x.divide(val).add(val).shiftRight(1);
if (xAsDub > 2e63) {
val = x.divide(val).add(val).shiftRight(1); }
}
else // handle large numbers over 4.3322e127
{
int xLen = x.bitLength();
int wantedPrecision = ((xLen + 1) / 2);
int xLenMod = xLen + (xLen & 1) + 1;
//////// Do the first Sqrt on Hardware ////////
long tempX = x.shiftRight(xLenMod - 63).longValue();
double tempSqrt1 = Math.sqrt(tempX);
long valLong = Double.doubleToLongBits(tempSqrt1) & 0x1fffffffffffffL;
if (valLong == 0)
valLong = 1L << 53;
//////// Classic Newton Iterations ////////
val = BigInteger.valueOf(valLong).shiftLeft(53 - 1)
.add((x.shiftRight(xLenMod -
(3 * 53))).divide(BigInteger.valueOf(valLong)));
int size = 106;
for (; size < 256; size <<= 1) {
val = val.shiftLeft(size - 1).add(x.shiftRight
(xLenMod - (3*size)).divide(val));}
if (xAsDub > 4e254) { // 4e254 = 1<<845.77
int numOfNewtonSteps = 31 -
Integer.numberOfLeadingZeros(wantedPrecision / size)+1;
////// Apply Starting Size ////////
int wantedSize = (wantedPrecision >> numOfNewtonSteps) + 2;
int needToShiftBy = size - wantedSize;
val = val.shiftRight(needToShiftBy);
size = wantedSize;
do {
//////// Newton Plus Iteration ////////
int shiftX = xLenMod - (3 * size);
BigInteger valSqrd = val.multiply(val).shiftLeft(size - 1);
BigInteger valSU = x.shiftRight(shiftX).subtract(valSqrd);
val = val.shiftLeft(size).add(valSU.divide(val));
size *= 2;
} while (size < wantedPrecision);
}
val = val.shiftRight(size - wantedPrecision);
}
// Detect a round ups. This function can be further optimized - see article.
// For a ~7% speed bump the following line can be removed but round-ups will occur.
if (val.multiply(val).compareTo(x) > 0)
val = val.subtract(BigInteger.ONE);
// Enabling the below will guarantee an error is stopped for larger numbers.
// Note: As of this writing, there are no known errors.
BigInteger tmp = val.multiply(val);
if (tmp.compareTo(x) > 0) {
System.out.println("val^2(" + val.multiply(val).toString()
+ ") ≥ x(" + x.toString()+")");
System.console().readLine();
//throw new Exception("Sqrt function had internal error - value too high");
}
if (tmp.add(val.shiftLeft(1)).add(BigInteger.ONE).compareTo(x) <= 0) {
System.out.println("(val+1)^2("
+ val.add(BigInteger.ONE).multiply(val.add(BigInteger.ONE)).toString()
+ ") ≥ x(" + x.toString() + ")");
System.console().readLine();
//throw new Exception("Sqrt function had internal error - value too low");
}
return val;
}
}
@@ -0,0 +1,39 @@
package com.baeldung.bigintegerroot;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.baeldung.bigintegerroot.algorithms.Newton;
import com.baeldung.bigintegerroot.algorithms.NewtonPlus;
import com.google.common.math.BigIntegerMath;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.stream.Stream;
import org.apache.commons.math3.util.Pair;
import org.junit.jupiter.api.condition.EnabledForJreRange;
import org.junit.jupiter.api.condition.JRE;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
class BigIntegerSquareRootUnitTest {
@ParameterizedTest
@ValueSource(strings = {
BigIntegerHolder.BIG_NUMBER,
BigIntegerHolder.VERY_BIG_NUMBER,
BigIntegerHolder.VERY_BIG_NUMBER
})
void squareRootTest(String number) {
final BigInteger bigInteger = new BigInteger(number);
final BigInteger javaRoot = bigInteger.sqrt();
final BigInteger guavaRoot = BigIntegerMath.sqrt(bigInteger, RoundingMode.DOWN);
final BigInteger newtonRoot = Newton.sqrt(bigInteger);
final BigInteger newtonPlusRoot = NewtonPlus.sqrt(bigInteger);
assertTrue(Stream.of(
new Pair<>(javaRoot, guavaRoot),
new Pair<>(guavaRoot, newtonRoot),
new Pair<>(newtonRoot, newtonPlusRoot)
).allMatch(pair -> pair.getFirst().equals(pair.getSecond())));
}
}
+1
View File
@@ -14,5 +14,6 @@ This module contains articles about working with the operating system (OS) in Ja
- [How to Run a Shell Command in Java](http://www.baeldung.com/run-shell-command-in-java)
- [Taking Screenshots Using Java](https://www.baeldung.com/java-taking-screenshots)
- [Java Sound API Capturing Microphone](https://www.baeldung.com/java-sound-api-capture-mic)
- [How to Detect the Username Using Java](https://www.baeldung.com/java-get-username)
This module uses Java 9, so make sure to have the JDK 9 installed to run it.
@@ -9,4 +9,5 @@
- [Regular Expression: \z vs \Z Anchors in Java](https://www.baeldung.com/java-regular-expression-z-vs-z-anchors)
- [Extract Text Between Square Brackets](https://www.baeldung.com/java-get-content-between-square-brackets)
- [Get the Indexes of Regex Pattern Matches in Java](https://www.baeldung.com/java-indexes-regex-pattern-matches)
- [Check if a String is Strictly Alphanumeric With Java](https://www.baeldung.com/java-check-string-contains-only-letters-numbers)
- More articles: [[<-- prev]](/core-java-modules/core-java-regex)