Czy istnieje lepszy sposób uzyskania długości int niż ta metoda?
int length = String.valueOf(1000).length();
Czy istnieje lepszy sposób uzyskania długości int niż ta metoda?
int length = String.valueOf(1000).length();
Odpowiedzi:
Twoje rozwiązanie oparte na łańcuchach znaków jest w porządku, nie ma w tym nic „nieuporządkowanego”. Musisz zdać sobie sprawę, że matematycznie liczby nie mają długości ani cyfr. Długość i cyfry są właściwościami fizycznej reprezentacji liczby w określonej bazie, tj. Ciągu znaków .
Rozwiązanie oparte na logarytmie wykonuje (niektóre) te same czynności, co rozwiązanie oparte na łańcuchach, i prawdopodobnie robi to (nieznacznie) szybciej, ponieważ generuje tylko długość i ignoruje cyfry. Ale tak naprawdę nie uważałbym tego za bardziej intencjonalne - i to jest najważniejszy czynnik.
Math.abs()
to jednak naprawi.
Logarytm jest twoim przyjacielem:
int n = 1000;
int length = (int)(Math.log10(n)+1);
NB: ważne tylko dla n> 0.
Najszybsze podejście: dziel i podbijaj.
Zakładając, że twój zakres wynosi od 0 do MAX_INT, to masz od 1 do 10 cyfr. Możesz zbliżyć się do tego przedziału za pomocą dzielenia i podbijania, z maksymalnie 4 porównaniami na każde wejście. Najpierw dzielisz [1..10] na [1..5] i [6..10] z jednym porównaniem, a następnie każdy przedział długości 5 dzielisz za pomocą jednego porównania na jeden przedział długości 3 i jeden przedział długości 2. Przedział długości 2 wymaga jeszcze jednego porównania (łącznie 3 porównania), przedział długości 3 można podzielić na przedział długości 1 (rozwiązanie) i przedział długości 2. Potrzebujesz więc 3 lub 4 porównań.
Bez podziałów, bez operacji zmiennoprzecinkowych, bez drogich logarytmów, tylko porównania liczb całkowitych.
Kod (długi, ale szybki):
if (n < 100000){
// 5 or less
if (n < 100){
// 1 or 2
if (n < 10)
return 1;
else
return 2;
}else{
// 3 or 4 or 5
if (n < 1000)
return 3;
else{
// 4 or 5
if (n < 10000)
return 4;
else
return 5;
}
}
} else {
// 6 or more
if (n < 10000000) {
// 6 or 7
if (n < 1000000)
return 6;
else
return 7;
} else {
// 8 to 10
if (n < 100000000)
return 8;
else {
// 9 or 10
if (n < 1000000000)
return 9;
else
return 10;
}
}
}
Test porównawczy (po rozgrzewce JVM) - zobacz poniższy kod, aby zobaczyć, jak uruchomiono test porównawczy:
Pełny kod:
public static void main(String[] args)
throws Exception
{
// validate methods:
for (int i = 0; i < 1000; i++)
if (method1(i) != method2(i))
System.out.println(i);
for (int i = 0; i < 1000; i++)
if (method1(i) != method3(i))
System.out.println(i + " " + method1(i) + " " + method3(i));
for (int i = 333; i < 2000000000; i += 1000)
if (method1(i) != method3(i))
System.out.println(i + " " + method1(i) + " " + method3(i));
for (int i = 0; i < 1000; i++)
if (method1(i) != method4(i))
System.out.println(i + " " + method1(i) + " " + method4(i));
for (int i = 333; i < 2000000000; i += 1000)
if (method1(i) != method4(i))
System.out.println(i + " " + method1(i) + " " + method4(i));
// work-up the JVM - make sure everything will be run in hot-spot mode
allMethod1();
allMethod2();
allMethod3();
allMethod4();
// run benchmark
Chronometer c;
c = new Chronometer(true);
allMethod1();
c.stop();
long baseline = c.getValue();
System.out.println(c);
c = new Chronometer(true);
allMethod2();
c.stop();
System.out.println(c + " = " + StringTools.formatDouble((double)baseline / c.getValue() , "0.00") + " times as fast as baseline");
c = new Chronometer(true);
allMethod3();
c.stop();
System.out.println(c + " = " + StringTools.formatDouble((double)baseline / c.getValue() , "0.00") + " times as fast as baseline");
c = new Chronometer(true);
allMethod4();
c.stop();
System.out.println(c + " = " + StringTools.formatDouble((double)baseline / c.getValue() , "0.00") + " times as fast as baseline");
}
private static int method1(int n)
{
return Integer.toString(n).length();
}
private static int method2(int n)
{
if (n == 0)
return 1;
return (int)(Math.log10(n) + 1);
}
private static int method3(int n)
{
if (n == 0)
return 1;
int l;
for (l = 0 ; n > 0 ;++l)
n /= 10;
return l;
}
private static int method4(int n)
{
if (n < 100000)
{
// 5 or less
if (n < 100)
{
// 1 or 2
if (n < 10)
return 1;
else
return 2;
}
else
{
// 3 or 4 or 5
if (n < 1000)
return 3;
else
{
// 4 or 5
if (n < 10000)
return 4;
else
return 5;
}
}
}
else
{
// 6 or more
if (n < 10000000)
{
// 6 or 7
if (n < 1000000)
return 6;
else
return 7;
}
else
{
// 8 to 10
if (n < 100000000)
return 8;
else
{
// 9 or 10
if (n < 1000000000)
return 9;
else
return 10;
}
}
}
}
private static int allMethod1()
{
int x = 0;
for (int i = 0; i < 1000; i++)
x = method1(i);
for (int i = 1000; i < 100000; i += 10)
x = method1(i);
for (int i = 100000; i < 1000000; i += 100)
x = method1(i);
for (int i = 1000000; i < 2000000000; i += 200)
x = method1(i);
return x;
}
private static int allMethod2()
{
int x = 0;
for (int i = 0; i < 1000; i++)
x = method2(i);
for (int i = 1000; i < 100000; i += 10)
x = method2(i);
for (int i = 100000; i < 1000000; i += 100)
x = method2(i);
for (int i = 1000000; i < 2000000000; i += 200)
x = method2(i);
return x;
}
private static int allMethod3()
{
int x = 0;
for (int i = 0; i < 1000; i++)
x = method3(i);
for (int i = 1000; i < 100000; i += 10)
x = method3(i);
for (int i = 100000; i < 1000000; i += 100)
x = method3(i);
for (int i = 1000000; i < 2000000000; i += 200)
x = method3(i);
return x;
}
private static int allMethod4()
{
int x = 0;
for (int i = 0; i < 1000; i++)
x = method4(i);
for (int i = 1000; i < 100000; i += 10)
x = method4(i);
for (int i = 100000; i < 1000000; i += 100)
x = method4(i);
for (int i = 1000000; i < 2000000000; i += 200)
x = method4(i);
return x;
}
Ponownie, punkt odniesienia:
Edycja: Po napisaniu testu porównawczego wziąłem podstęp do Integer.toString z Java 6 i stwierdziłem, że używa:
final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
99999999, 999999999, Integer.MAX_VALUE };
// Requires positive x
static int stringSize(int x) {
for (int i=0; ; i++)
if (x <= sizeTable[i])
return i+1;
}
Porównałem go z moim rozwiązaniem „dziel i rządź”:
Mój jest około 4x szybszy niż rozwiązanie Java 6.
n<100000?n<100?n<10?1:2:n<1000?3:n<10000?4:5:n<10000000?n<1000000?6:7:n<100000000?8:n<1000000000?9:10
Dwa komentarze na temat twojego testu porównawczego: Java jest złożonym środowiskiem, z kompilacją „just-in-time” i zbieraniem śmieci itd. Aby uzyskać rzetelne porównanie za każdym razem, gdy uruchamiam test porównawczy, zawsze: (a) załączam dwa testy w pętli, która uruchamia je kolejno 5 lub 10 razy. Dość często środowisko uruchomieniowe przy drugim przejściu przez pętlę jest zupełnie inne niż pierwsze. I (b) Po każdym „podejściu” wykonuję System.gc (), aby spróbować wyrzucić śmieci. W przeciwnym razie pierwsze podejście może wygenerować wiązkę obiektów, ale niewystarczająco do wymuszenia wyrzucania elementów bezużytecznych, następnie drugie podejście tworzy kilka obiektów, stos jest wyczerpany i następuje odśmiecanie. Następnie drugie podejście jest „naliczane” za zbieranie śmieci pozostawionych przez pierwsze podejście. Bardzo niesprawiedliwie!
To powiedziawszy, żadne z powyższych nie miało znaczącej różnicy w tym przykładzie.
Z tymi modyfikacjami lub bez nich uzyskałem zupełnie inne wyniki niż ty. Kiedy to uruchomiłem, tak, podejście toString dało czasy działania od 6400 do 6600 milis, podczas gdy podejście logarytmiczne wynosi od 20 000 do 20 400 milis. Zamiast być nieco szybszym, podejście do dziennika było dla mnie 3 razy wolniejsze.
Zauważ, że oba podejścia wiążą się z bardzo różnymi kosztami, więc nie jest to całkowicie szokujące: podejście toString stworzy wiele tymczasowych obiektów, które muszą zostać oczyszczone, podczas gdy podejście oparte na logach wymaga bardziej intensywnych obliczeń. Być może różnica polega na tym, że na komputerze z mniejszą pamięcią toString wymaga więcej rund wyrzucania elementów bezużytecznych, podczas gdy na komputerze z wolniejszym procesorem dodatkowe obliczenie dziennika byłoby bardziej bolesne.
Próbowałem także trzeciego podejścia. Napisałem tę małą funkcję:
static int numlength(int n)
{
if (n == 0) return 1;
int l;
n=Math.abs(n);
for (l=0;n>0;++l)
n/=10;
return l;
}
Działało to od 1600 do 1900 milis - mniej niż 1/3 podejścia toString i 1/10 logarytmu podejścia na mojej maszynie.
Jeśli dysponujesz szerokim zakresem liczb, możesz go jeszcze przyspieszyć, zaczynając od podzielenia przez 1 000 lub 1 000 000, aby zmniejszyć liczbę razy w pętli. Nie grałem z tym.
Korzystanie z Java
int nDigits = Math.floor(Math.log10(Math.abs(the_integer))) + 1;
użyj import java.lang.Math.*;
na początku
Korzystanie z C.
int nDigits = floor(log10(abs(the_integer))) + 1;
użyj inclue math.h
na początku
the_integer
jest 0
, więc sprawdź to.
Nie mogę jeszcze zostawić komentarza, więc opublikuję jako osobną odpowiedź.
Rozwiązanie oparte na logarytmie nie oblicza poprawnej liczby cyfr dla bardzo dużych długich liczb całkowitych, na przykład:
long n = 99999999999999999L;
// correct answer: 17
int numberOfDigits = String.valueOf(n).length();
// incorrect answer: 18
int wrongNumberOfDigits = (int) (Math.log10(n) + 1);
Rozwiązanie oparte na logarytmach oblicza niepoprawną liczbę cyfr w dużych liczbach całkowitych
Ponieważ liczba cyfr w podstawie 10 liczby całkowitej wynosi tylko 1 + obcięcie (log10 (liczba)) , możesz:
public class Test {
public static void main(String[] args) {
final int number = 1234;
final int digits = 1 + (int)Math.floor(Math.log10(number));
System.out.println(digits);
}
}
Edytowane, ponieważ moja ostatnia edycja naprawiła przykład kodu, ale nie opis.
Math.floor
jest trochę zbędne, prawda? Zrealizowanie i int
tak zaokrągli to w dół.
Rozwiązanie Mariana dostosowane do liczb długich (do 9 223 372,036,854,775,807) na wypadek, gdyby ktoś chciał je skopiować i wkleić. W programie napisałem to dla liczb do 10000, które były znacznie bardziej prawdopodobne, więc stworzyłem dla nich specjalną gałąź. W każdym razie nie zrobi to znaczącej różnicy.
public static int numberOfDigits (long n) {
// Guessing 4 digit numbers will be more probable.
// They are set in the first branch.
if (n < 10000L) { // from 1 to 4
if (n < 100L) { // 1 or 2
if (n < 10L) {
return 1;
} else {
return 2;
}
} else { // 3 or 4
if (n < 1000L) {
return 3;
} else {
return 4;
}
}
} else { // from 5 a 20 (albeit longs can't have more than 18 or 19)
if (n < 1000000000000L) { // from 5 to 12
if (n < 100000000L) { // from 5 to 8
if (n < 1000000L) { // 5 or 6
if (n < 100000L) {
return 5;
} else {
return 6;
}
} else { // 7 u 8
if (n < 10000000L) {
return 7;
} else {
return 8;
}
}
} else { // from 9 to 12
if (n < 10000000000L) { // 9 or 10
if (n < 1000000000L) {
return 9;
} else {
return 10;
}
} else { // 11 or 12
if (n < 100000000000L) {
return 11;
} else {
return 12;
}
}
}
} else { // from 13 to ... (18 or 20)
if (n < 10000000000000000L) { // from 13 to 16
if (n < 100000000000000L) { // 13 or 14
if (n < 10000000000000L) {
return 13;
} else {
return 14;
}
} else { // 15 or 16
if (n < 1000000000000000L) {
return 15;
} else {
return 16;
}
}
} else { // from 17 to ...¿20?
if (n < 1000000000000000000L) { // 17 or 18
if (n < 100000000000000000L) {
return 17;
} else {
return 18;
}
} else { // 19? Can it be?
// 10000000000000000000L is'nt a valid long.
return 19;
}
}
}
}
}
Co powiesz na zwykłą starą matematykę? Dziel przez 10, aż osiągniesz 0.
public static int getSize(long number) {
int count = 0;
while (number > 0) {
count += 1;
number = (number / 10);
}
return count;
}
Long.MAX_VALUE
, która jest najgorszym przypadkiem złożoności twojego kodu, i wykorzystaj, System.nanoTime()
aby wykonać próbę taktowania w odniesieniu do najgorszych przypadków złożoności drugiego rozwiązania. ++ Faktycznie, spróbuj go z tablicy wypełnionej przez zestaw Randomizer do zakresu 0
do Long.MAX_VALUE
zbyt, tylko dla „przeciętnego złożoności” Testowanie ++ Można znaleźć wyników ... bardzo szokujące.
int,
tej pętli wykonuje się maksymalnie 11 razy. Czy masz jakieś dowody na swoje twierdzenia?
Rozwiązanie Mariana, teraz z Ternary:
public int len(int n){
return (n<100000)?((n<100)?((n<10)?1:2):(n<1000)?3:((n<10000)?4:5)):((n<10000000)?((n<1000000)?6:7):((n<100000000)?8:((n<1000000000)?9:10)));
}
Ponieważ możemy.
Ciekawe, próbowałem to porównać ...
import org.junit.Test;
import static org.junit.Assert.*;
public class TestStack1306727 {
@Test
public void bench(){
int number=1000;
int a= String.valueOf(number).length();
int b= 1 + (int)Math.floor(Math.log10(number));
assertEquals(a,b);
int i=0;
int s=0;
long startTime = System.currentTimeMillis();
for(i=0, s=0; i< 100000000; i++){
a= String.valueOf(number).length();
s+=a;
}
long stopTime = System.currentTimeMillis();
long runTime = stopTime - startTime;
System.out.println("Run time 1: " + runTime);
System.out.println("s: "+s);
startTime = System.currentTimeMillis();
for(i=0,s=0; i< 100000000; i++){
b= number==0?1:(1 + (int)Math.floor(Math.log10(Math.abs(number))));
s+=b;
}
stopTime = System.currentTimeMillis();
runTime = stopTime - startTime;
System.out.println("Run time 2: " + runTime);
System.out.println("s: "+s);
assertEquals(a,b);
}
}
wyniki są następujące:
Czas działania 1: 6765 s: 400000000 Czas pracy 2: 6000 s: 400000000
Teraz zastanawiam się, czy mój test porównawczy rzeczywiście coś znaczy, ale otrzymuję spójne wyniki (zmiany w ciągu ms) w wielu testach samego testu ... :) Wygląda na to, że nie ma sensu próbować optymalizować tego ...
edytuj: w następstwie komentarza ptomli zastąpiłem „numer” przez „i” w powyższym kodzie i uzyskałem następujące wyniki w ciągu 5 przebiegów stanowiska:
Czas działania 1: 11500 s: 788888890 Czas wykonywania 2: 8547 s: 788888890 Czas działania 1: 11485 s: 788888890 Czas wykonywania 2: 8547 s: 788888890 Czas wykonania 1: 11469 s: 788888890 Czas wykonywania 2: 8547 s: 788888890 Czas działania 1: 11500 s: 788888890 Czas wykonywania 2: 8547 s: 788888890 Czas wykonywania 1: 11484 s: 788888890 Czas wykonywania 2: 8547 s: 788888890
Naprawdę proste rozwiązanie:
public int numLength(int n) {
for (int length = 1; n % Math.pow(10, length) != n; length++) {}
return length;
}
Lub zamiast tego możesz sprawdzić, czy liczba jest większa czy mniejsza niż żądana liczba.
public void createCard(int cardNumber, int cardStatus, int customerId) throws SQLException {
if(cardDao.checkIfCardExists(cardNumber) == false) {
if(cardDao.createCard(cardNumber, cardStatus, customerId) == true) {
System.out.println("Card created successfully");
} else {
}
} else {
System.out.println("Card already exists, try with another Card Number");
do {
System.out.println("Enter your new Card Number: ");
scan = new Scanner(System.in);
int inputCardNumber = scan.nextInt();
cardNumber = inputCardNumber;
} while(cardNumber < 95000000);
cardDao.createCard(cardNumber, cardStatus, customerId);
}
}
}
Nie widziałem jeszcze rozwiązania opartego na mnożeniu. Rozwiązania oparte na logarytmie, dywizji i łańcuchach staną się raczej niewygodne w stosunku do milionów przypadków testowych, więc oto jeden z nich ints
:
/**
* Returns the number of digits needed to represents an {@code int} value in
* the given radix, disregarding any sign.
*/
public static int len(int n, int radix) {
radixCheck(radix);
// if you want to establish some limitation other than radix > 2
n = Math.abs(n);
int len = 1;
long min = radix - 1;
while (n > min) {
n -= min;
min *= radix;
len++;
}
return len;
}
W bazie 10 działa to, ponieważ n jest zasadniczo porównywane z 9, 99, 999 ... tak jak min wynosi 9, 90, 900 ... a n jest odejmowane przez 9, 90, 900 ...
Niestety, nie jest to przenośne po long
prostu przez zastąpienie każdego wystąpienia z int
powodu przepełnienia. Z drugiej strony tak się składa, że będzie działał dla baz 2 i 10 (ale w przypadku większości innych baz bardzo się nie powiedzie). Potrzebujesz tabeli przeglądowej dla punktów przepełnienia (lub testu podziału ... ew)
/**
* For radices 2 &le r &le Character.MAX_VALUE (36)
*/
private static long[] overflowpt = {-1, -1, 4611686018427387904L,
8105110306037952534L, 3458764513820540928L, 5960464477539062500L,
3948651115268014080L, 3351275184499704042L, 8070450532247928832L,
1200757082375992968L, 9000000000000000000L, 5054470284992937710L,
2033726847845400576L, 7984999310198158092L, 2022385242251558912L,
6130514465332031250L, 1080863910568919040L, 2694045224950414864L,
6371827248895377408L, 756953702320627062L, 1556480000000000000L,
3089447554782389220L, 5939011215544737792L, 482121737504447062L,
839967991029301248L, 1430511474609375000L, 2385723916542054400L,
3902460517721977146L, 6269893157408735232L, 341614273439763212L,
513726300000000000L, 762254306892144930L, 1116892707587883008L,
1617347408439258144L, 2316231840055068672L, 3282671350683593750L,
4606759634479349760L};
public static int len(long n, int radix) {
radixCheck(radix);
n = abs(n);
int len = 1;
long min = radix - 1;
while (n > min) {
len++;
if (min == overflowpt[radix]) break;
n -= min;
min *= radix;
}
return len;
}
Z projektem (w oparciu o problem). Jest to alternatywa podziału i podboju. Najpierw zdefiniujemy wyliczenie (biorąc pod uwagę, że dotyczy tylko int bez znaku).
public enum IntegerLength {
One((byte)1,10),
Two((byte)2,100),
Three((byte)3,1000),
Four((byte)4,10000),
Five((byte)5,100000),
Six((byte)6,1000000),
Seven((byte)7,10000000),
Eight((byte)8,100000000),
Nine((byte)9,1000000000);
byte length;
int value;
IntegerLength(byte len,int value) {
this.length = len;
this.value = value;
}
public byte getLenght() {
return length;
}
public int getValue() {
return value;
}
}
Teraz zdefiniujemy klasę, która przejdzie wartości wyliczenia i porówna i zwróci odpowiednią długość.
public class IntegerLenght {
public static byte calculateIntLenght(int num) {
for(IntegerLength v : IntegerLength.values()) {
if(num < v.getValue()){
return v.getLenght();
}
}
return 0;
}
}
Czas działania tego rozwiązania jest taki sam, jak w przypadku metody „dziel i rządź”.
num>=Nine.getValue()
?
Ktoś chce to zrobić głównie dlatego, że chce ją „przedstawić”, co w większości oznacza, że w końcu należy ją „poddać edycji” (lub przekształcić w inny sposób), jawnie lub pośrednio; zanim będzie można go przedstawić (na przykład wydrukować).
Jeśli tak jest, po prostu spróbuj jawnie określić „toString” i policz bity.
Możemy to osiągnąć za pomocą pętli rekurencyjnej
public static int digitCount(int numberInput, int i) {
while (numberInput > 0) {
i++;
numberInput = numberInput / 10;
digitCount(numberInput, i);
}
return i;
}
public static void printString() {
int numberInput = 1234567;
int digitCount = digitCount(numberInput, 0);
System.out.println("Count of digit in ["+numberInput+"] is ["+digitCount+"]");
}
Napisałem tę funkcję po sprawdzeniu Integer.java
kodu źródłowego.
private static int stringSize(int x) {
final int[] sizeTable = {9, 99, 999, 9_999, 99_999, 999_999, 9_999_999,
99_999_999, 999_999_999, Integer.MAX_VALUE};
for (int i = 0; ; ++i) {
if (x <= sizeTable[i]) {
return i + 1;
}
}
}
Widzę ludzi korzystających z bibliotek String, a nawet korzystających z klasy Integer. Nie ma w tym nic złego, ale algorytm uzyskiwania liczby cyfr nie jest tak skomplikowany. Używam długi w tym przykładzie, ale działa równie dobrze z int.
private static int getLength(long num) {
int count = 1;
while (num >= 10) {
num = num / 10;
count++;
}
return count;
}
bez interfejsu API napisów, bez narzędzi, bez konwersji typu, po prostu iteracja w java ->
public static int getNumberOfDigits(int input) {
int numOfDigits = 1;
int base = 1;
while (input >= base * 10) {
base = base * 10;
numOfDigits++;
}
return numOfDigits;
}
Jeśli chcesz, możesz długo szukać większych wartości.
Łatwy sposób rekurencyjny
int get_int_lenght(current_lenght, value)
{
if (value / 10 < 10)
return (current_lenght + 1);
return (get_int_lenght(current_lenght + 1, value))
}
nie testowany
Mógłbyś cyfry, stosując kolejne dzielenie przez dziesięć:
int a=0;
if (no < 0) {
no = -no;
} else if (no == 0) {
no = 1;
}
while (no > 0) {
no = no / 10;
a++;
}
System.out.println("Number of digits in given number is: "+a);
Wprowadź numer i utwórz Arraylist
, a pętla while zapisze wszystkie cyfry w Arraylist
. Następnie możemy wyjąć rozmiar tablicy, który będzie długością wprowadzonej wartości całkowitej.
ArrayList<Integer> a=new ArrayList<>();
while(number > 0)
{
remainder = num % 10;
a.add(remainder);
number = number / 10;
}
int m=a.size();
Oto bardzo prosta metoda, którą stworzyłem, która działa dla dowolnej liczby:
public static int numberLength(int userNumber) {
int numberCounter = 10;
boolean condition = true;
int digitLength = 1;
while (condition) {
int numberRatio = userNumber / numberCounter;
if (numberRatio < 1) {
condition = false;
} else {
digitLength++;
numberCounter *= 10;
}
}
return digitLength;
}
Działa ze zmienną licznika liczb w taki sposób, że 10 = 1 cyfra. Na przykład .1 = 1 dziesiąta => 1 cyfra. Dlatego jeśli masz int number = 103342;
, dostaniesz 6, ponieważ jest to równowartość 0,000001 spacji z powrotem. Ponadto, czy ktoś ma lepszą nazwę zmiennej numberCounter
? Nie mogę wymyślić nic lepszego.
Edycja: Pomyślałem o lepszym wyjaśnieniu. Zasadniczo to, co robi ta pętla while, polega na dzieleniu liczby przez 10, aż będzie mniejsza niż jeden. Zasadniczo, dzieląc coś przez 10, przesuwasz je o jedną spację liczbową, więc po prostu dziel to przez 10, aż osiągniesz <1 dla liczby cyfr w liczbie.
Oto kolejna wersja, która może liczyć liczbę cyfr po przecinku:
public static int repeatingLength(double decimalNumber) {
int numberCounter = 1;
boolean condition = true;
int digitLength = 1;
while (condition) {
double numberRatio = decimalNumber * numberCounter;
if ((numberRatio - Math.round(numberRatio)) < 0.0000001) {
condition = false;
} else {
digitLength++;
numberCounter *= 10;
}
}
return digitLength - 1;
}
Spróbuj przekonwertować int do łańcucha , a następnie uzyskać długość łańcucha . To powinno uzyskać długość int .
public static int intLength(int num){
String n = Integer.toString(num);
int newNum = n.length();
return newNum;
}
number
będzie negatywny.