Bir int uzunluğunu elde etmek için bu yöntemden daha temiz bir yol var mı?
int length = String.valueOf(1000).length();
Bir int uzunluğunu elde etmek için bu yöntemden daha temiz bir yol var mı?
int length = String.valueOf(1000).length();
Yanıtlar:
Dize tabanlı çözümünüz gayet iyi, bu konuda "düzgün" hiçbir şey yok. Matematiksel olarak, sayıların uzunluğunun veya rakamlarının olmadığını fark etmelisiniz. Uzunluk ve basamaklar, belirli bir tabandaki bir sayının fiziksel bir temsilinin , yani bir String'in özellikleridir.
Logaritma tabanlı bir çözüm, String tabanlı olanın dahili olarak yaptığı şeylerin bazılarını (bazıları) yapar ve muhtemelen (önemsiz olarak) daha hızlı yapar çünkü yalnızca uzunluğu üretir ve rakamları yok sayar. Ama aslında bunu daha net olarak düşünmezdim - ve bu en önemli faktör.
Math.abs()
bunu düzeltir.
Logaritma senin arkadaşın:
int n = 1000;
int length = (int)(Math.log10(n)+1);
Not: sadece n> 0 için geçerlidir.
En hızlı yaklaşım: böl ve fethet.
Aralığınızın 0 ila MAX_INT olduğunu varsayarsak, 1 ila 10 rakamınız vardır. Bu aralığa, her giriş için en fazla 4 karşılaştırma ile böl ve fethet komutunu kullanarak yaklaşabilirsiniz. İlk olarak, bir karşılaştırma ile [1..10] 'u [1..5] ve [6..10]' a böldükten sonra, her bir uzunluk 5 aralığını bir karşılaştırma 3 ile bir uzunluk 2 aralığına böldüğünüz. Uzunluk 2 aralığı bir daha karşılaştırma (toplam 3 karşılaştırma) gerektirir, uzunluk 3 aralığı uzunluk 1 aralığına (çözelti) ve uzunluk 2 aralığına bölünebilir. Yani, 3 veya 4 karşılaştırmaya ihtiyacınız var.
Bölme yok, kayan nokta işlemi yok, pahalı logaritma yok, sadece tamsayı karşılaştırma.
Kod (uzun ama hızlı):
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;
}
}
}
Karşılaştırma ölçütü (JVM ısınmasından sonra) - karşılaştırmalı değerlendirmenin nasıl yürütüldüğünü görmek için aşağıdaki koda bakın:
Tam 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;
}
Yine, karşılaştırma ölçütü:
Düzenleme: Ben kriter yazdıktan sonra, Java 6 Integer.toString içine gizlice bir tepe aldı ve ben kullanır:
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;
}
Böl ve fethet çözümümle karşılaştırdım:
Benimki Java 6 çözümünden yaklaşık 4 kat daha hızlı.
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
Karşılaştırmanız hakkında iki yorum: Java, tam zamanında derleme ve çöp toplama vb.İle karmaşık bir ortamdır, bu nedenle adil bir karşılaştırma elde etmek için, her kıyaslama yaptığımda, her zaman: (a) iki testi de dahil ediyorum 5 veya 10 kez sırayla çalıştıran bir döngüde. Çoğunlukla döngüden ikinci geçişteki çalışma süresi birinciden oldukça farklıdır. Ve (b) Her "yaklaşım" dan sonra, bir çöp toplama tetiklemek için bir System.gc () yapmak. Aksi takdirde, ilk yaklaşım bir grup nesne oluşturabilir, ancak bir çöp koleksiyonunu zorlamak için yeterli değildir, daha sonra ikinci yaklaşım birkaç nesne oluşturur, yığın tükenir ve çöp toplama çalışır. Daha sonra ikinci yaklaşım, ilk yaklaşımın bıraktığı çöpleri toplamak için "yüklenir". Çok haksız!
Bununla birlikte, yukarıdakilerin hiçbiri bu örnekte önemli bir fark yaratmadı.
Bu modifikasyonlarla veya modifikasyonlar olmadan, sizden çok farklı sonuçlar aldım. Bunu çalıştırdığımda, evet, toString yaklaşımı 6400 ila 6600 milis çalışma süreleri verirken, günlük yaklaşımı 20.000 ila 20.400 milis topok verdi. Biraz daha hızlı olmak yerine, günlük yaklaşımı benim için 3 kat daha yavaştı.
İki yaklaşımın çok farklı maliyetler içerdiğini unutmayın, bu tamamen şok edici değildir: toString yaklaşımı, temizlenmesi gereken çok sayıda geçici nesne yaratırken günlük yaklaşımı daha yoğun hesaplama gerektirir. Bu yüzden belki de fark, daha az belleğe sahip bir makinede, toString'in daha fazla çöp toplama turu gerektirmesi, daha yavaş işlemciye sahip bir makinede ise, fazladan günlük hesaplaması daha acı verici olacaktır.
Ayrıca üçüncü bir yaklaşım denedim. Bu küçük işlevi yazdım:
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;
}
Bu 1600 ila 1900 milisaniyede koştu - toString yaklaşımının 1 / 3'ünden daha az ve makinemdeki günlük yaklaşımının 1 / 10'u.
Geniş bir sayı aralığınız varsa, döngüdeki sayısını azaltmak için 1.000 veya 1.000.000'a bölünerek başlatabilirsiniz. Bununla oynamadım.
Java Kullanımı
int nDigits = Math.floor(Math.log10(Math.abs(the_integer))) + 1;
kullanmak import java.lang.Math.*;
başında
C Kullanımı
int nDigits = floor(log10(abs(the_integer))) + 1;
kullanmak inclue math.h
başında
the_integer
olur 0
, bu yüzden kontrol edin.
Henüz yorum bırakamıyorum, bu yüzden ayrı bir cevap olarak göndereceğim.
Logaritma tabanlı çözüm, çok büyük uzun tamsayılar için doğru basamak sayısını hesaplamaz, örneğin:
long n = 99999999999999999L;
// correct answer: 17
int numberOfDigits = String.valueOf(n).length();
// incorrect answer: 18
int wrongNumberOfDigits = (int) (Math.log10(n) + 1);
Logaritma tabanlı çözüm, büyük tamsayılarda yanlış basamak sayısını hesaplar
Bir tamsayının 10 tabanındaki basamak sayısı sadece 1 + kısaltma (log10 (sayı)) olduğundan , şunları yapabilirsiniz:
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);
}
}
Düzenlenen benim son düzenleme açıklama kod örneği sabit değil çünkü.
Math.floor
Bu biraz gereksiz değil mi? Döküm int
yine de yuvarlar.
Marian'ın çözümü , biri kopyalamak ve yapıştırmak istemesi durumunda, uzun tip sayılarına uyarlanmıştır (9,223,372,036,854,775,807'ye kadar). Programda bu sayıyı 10000'e kadar olan rakamlar için çok daha olası yazdım, bu yüzden onlar için belirli bir dal yaptım. Her neyse önemli bir fark yaratmayacak.
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;
}
}
}
}
}
Sade eski matematiğe ne dersiniz? 0'a ulaşıncaya kadar 10'a bölün.
public static int getSize(long number) {
int count = 0;
while (number > 0) {
count += 1;
number = (number / 10);
}
return count;
}
Long.MAX_VALUE
Kodunuzun en kötü karmaşıklık durumu olan iki milyon sayıdan oluşan bir dizi yapın System.nanoTime()
ve diğer çözümün en kötü karmaşıklık durumlarına karşı bir saatli deneme yapmak için kullanın . ++ Aslında aralığına rasgeleleştirici kümesi tarafından doldurulan bir dizi denemek 0
için Long.MAX_VALUE
sadece Çok şoke ... sonuçlarını bulabilirsiniz ++ test "ortalama karmaşıklığı" için de.
int,
bu döngü maksimum 11 kez yürütülür. İddialarınız için kanıtınız var mı?
Marian's Solution, şimdi Ternary ile:
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)));
}
Çünkü yapabiliriz.
Meraklı, ben kıyaslamaya çalıştım ...
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);
}
}
sonuçlar:
Çalışma süresi 1: 6765 s: 400000000 Çalışma süresi 2: 6000 s: 400000000
Şimdi kıyaslamamın gerçekten bir şey ifade edip etmediğini merak ediyorum ama kıyaslamanın kendisinin birden fazla çalışması üzerinde tutarlı sonuçlar (bir ms içinde varyasyonlar) alıyorum ... :) Bunu denemek ve optimize etmek işe yaramaz gibi görünüyor ...
edit: ptomli'nin yorumunu takiben, yukarıdaki kodda 'sayı'yı' i 'ile değiştirdim ve tezgahın 5 çalışmasında aşağıdaki sonuçları aldım:
Çalışma süresi 1: 11500 s: 788888890 Çalışma süresi 2: 8547 s: 788888890 Çalışma süresi 1: 11485 s: 788888890 Çalışma süresi 2: 8547 s: 788888890 Çalışma süresi 1: 11469 s: 788888890 Çalışma süresi 2: 8547 s: 788888890 Çalışma süresi 1: 11500 s: 788888890 Çalışma süresi 2: 8547 s: 788888890 Çalışma süresi 1: 11484 s: 788888890 Çalışma süresi 2: 8547 s: 788888890
Gerçekten basit bir çözüm:
public int numLength(int n) {
for (int length = 1; n % Math.pow(10, length) != n; length++) {}
return length;
}
Ya da bunun yerine uzunluk, sayının istenen sayıdan daha büyük veya daha küçük olup olmadığını kontrol edebilirsiniz.
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);
}
}
}
Henüz çarpma tabanlı bir çözüm görmedim. Logaritma, bölme ve dizi tabanlı çözümler milyonlarca test vakasına karşı oldukça kullanışsız olacaktır, bu yüzden aşağıdakilerden biri 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;
}
Taban 10'da, bu işe yarar çünkü n aslında 9, 99, 999 ile karşılaştırılır ... çünkü min 9, 90, 900 ... ve n 9, 90, 900 ile çıkarılır ...
Ne yazık ki, bu long
sadece int
taşma nedeniyle her örneğini değiştirerek taşınabilir değildir . Öte yandan, sadece bu yüzden olur edecektir üsleri 2 ve 10 için çalışmak (ama kötü diğer üslerin çoğu için başarısız). Taşma noktaları için bir arama tablosuna ihtiyacınız olacak (veya bir bölüm testi ... 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;
}
Tasarım ile (probleme dayalı). Bu, bölün ve fethetmenin bir alternatifidir. İlk önce bir numaralandırma tanımlayacağız (sadece işaretsiz bir int için olduğunu düşünüyoruz).
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;
}
}
Şimdi sıralamanın değerlerinden geçen bir sınıf tanımlayacağız ve uygun uzunluğu karşılaştıracağız.
public class IntegerLenght {
public static byte calculateIntLenght(int num) {
for(IntegerLength v : IntegerLength.values()) {
if(num < v.getValue()){
return v.getLenght();
}
}
return 0;
}
}
Bu çözümün çalışma süresi böl ve fethet yaklaşımıyla aynıdır.
num>=Nine.getValue()
?
Kişi bunu çoğunlukla "sunmak" istediği için yapmak ister, bu da eninde sonunda açıkça veya dolaylı olarak "toString-ed" (veya başka bir şekilde dönüştürülmüş) olması gerektiği anlamına gelir; sunulmadan önce (örneğin basılı).
Eğer durum buysa, gerekli "toString" i açık hale getirmeye çalışın ve bitleri sayın.
Bunu yinelemeli bir döngü kullanarak başarabiliriz
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+"]");
}
Bu işlevi Integer.java
kaynak koduna baktıktan sonra yazdım .
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;
}
}
}
String kütüphaneleri kullanan, hatta Integer sınıfını kullanan insanlar görüyorum. Bunda yanlış bir şey yok ama basamak sayısını elde etme algoritması o kadar karmaşık değil. Bu örnekte uzun bir süre kullanıyorum ama bir int ile gayet iyi çalışıyor.
private static int getLength(long num) {
int count = 1;
while (num >= 10) {
num = num / 10;
count++;
}
return count;
}
hiçbir String API, hiçbir yarar, hiçbir tür dönüştürme, sadece saf java yineleme ->
public static int getNumberOfDigits(int input) {
int numOfDigits = 1;
int base = 1;
while (input >= base * 10) {
base = base * 10;
numOfDigits++;
}
return numOfDigits;
}
İsterseniz daha büyük değerler için uzun sürebilirsin.
Kolay özyinelemeli yol
int get_int_lenght(current_lenght, value)
{
if (value / 10 < 10)
return (current_lenght + 1);
return (get_int_lenght(current_lenght + 1, value))
}
test edilmedi
Rakamları art arda on kullanarak bölme yapabilirsiniz:
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);
Numarayı girin ve bir oluşturun Arraylist
, while döngüsü tüm basamakları Arraylist
. Ardından, girdiğiniz tamsayı değerinin uzunluğu olan dizinin boyutunu çıkarabiliriz.
ArrayList<Integer> a=new ArrayList<>();
while(number > 0)
{
remainder = num % 10;
a.add(remainder);
number = number / 10;
}
int m=a.size();
İşte herhangi bir sayı için çalışan gerçekten basit bir yöntem:
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;
}
Sayı sayacı değişkeni ile çalışma şekli 10 = 1 basamaklı boşluktur. Örneğin .1 = 1 onda biri => 1 basamaklı boşluk. Bu nedenle int number = 103342;
, 6 elde edersiniz, çünkü bu geri .000001 boşluklarına eşdeğerdir. Ayrıca, herkes için daha iyi bir değişken adı var numberCounter
mı? Daha iyi bir şey düşünemiyorum.
Edit: Sadece daha iyi bir açıklama düşündüm. Temelde bu döngü yaparken bunu yapmak, böylece numaranızı bire kadar olana kadar 10'a bölmenizdir. Temel olarak, bir şeyi 10'a böldüğünüzde, onu bir sayı boşluğuna geri taşırsınız, bu nedenle sayınızdaki basamak miktarı için <1'e ulaşıncaya kadar onu 10'a bölersiniz.
Ondalık bir sayıdaki sayı miktarını sayabilen başka bir sürüm:
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;
}
Dönüştürmeyi deneyin int a dize ve sonra uzunluğunu almak dize . Bu int uzunluğunu almak gerekir .
public static int intLength(int num){
String n = Integer.toString(num);
int newNum = n.length();
return newNum;
}
number
negatif olduğunda özleyeceğim .