Java 获取整数位数的方法?
有没有比这种方法更简洁的方法来获取整数的位数Java 获取整数位数的方法?,java,integer,Java,Integer,有没有比这种方法更简洁的方法来获取整数的位数 int numDigits = String.valueOf(1000).length(); 对数是你的朋友: int n = 1000; int length = (int)(Math.log10(n)+1); 注意:仅对n>0有效。由于整数以10为底的位数仅为1+truncate(log10(number)),因此可以执行以下操作: public class Test { public static void main(String
int numDigits = String.valueOf(1000).length();
对数是你的朋友:
int n = 1000;
int length = (int)(Math.log10(n)+1);
注意:仅对n>0有效。由于整数以10为底的位数仅为1+truncate(log10(number)),因此可以执行以下操作:
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);
}
}
已编辑,因为我上次编辑修复了代码示例,但没有修复描述。基于字符串的解决方案非常好,没有任何“不整洁”的地方。你必须意识到,从数学上讲,数字没有长度,也没有数字。长度和数字都是数字在特定基(即字符串)中的物理表示的属性 基于对数的解决方案与基于字符串的解决方案在内部所做的(某些)相同,而且可能更快(微不足道),因为它只生成长度而忽略数字。但我并不认为它在意图上更清晰,这是最重要的因素。我可以试试吗?p> 基于德克解
final int digits = number==0?1:(1 + (int)Math.floor(Math.log10(Math.abs(number))));
出于好奇,我试着对它进行基准测试
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);
}
}
import org.junit.Test;
导入静态org.junit.Assert.*;
公共类TestStack1306727{
@试验
公众席(){
整数=1000;
int a=String.valueOf(number).length();
INTB=1+(int)数学楼层(数学日志10(数字));
资产质量(a、b);
int i=0;
int s=0;
long startTime=System.currentTimeMillis();
对于(i=0,s=0;i<100000000;i++){
a=字符串.valueOf(number).length();
s+=a;
}
长停止时间=System.currentTimeMillis();
长时间运行=停止时间-开始时间;
System.out.println(“运行时1:+运行时”);
System.out.println(“s:+s”);
startTime=System.currentTimeMillis();
对于(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();
运行时=停止时间-开始时间;
System.out.println(“运行时2:+运行时”);
System.out.println(“s:+s”);
资产质量(a、b);
}
}
结果是:
Run time 1: 6765
s: 400000000
Run time 2: 6000
s: 400000000
运行时间1:6765
s:400000000
运行时间2:6000
s:400000000
现在我想知道我的基准测试是否真的意味着什么,但我确实在多次运行基准测试本身时得到了一致的结果(一个毫秒内的变化…:)看起来尝试优化这个是没有用的
编辑:根据托姆利的评论,我在上面的代码中将“number”替换为“I”,并在5次试验台运行中得到以下结果: Run time 1: 11500 s: 788888890 Run time 2: 8547 s: 788888890 Run time 1: 11485 s: 788888890 Run time 2: 8547 s: 788888890 Run time 1: 11469 s: 788888890 Run time 2: 8547 s: 788888890 Run time 1: 11500 s: 788888890 Run time 2: 8547 s: 788888890 Run time 1: 11484 s: 788888890 Run time 2: 8547 s: 788888890 运行时间1:11500 s:7888890 运行时间2:8547 s:7888890 运行时间1:11485 s:7888890 运行时间2:8547 s:7888890 运行时间1:11469 s:7888890 运行时间2:8547 s:7888890 运行时间1:11500 s:7888890 运行时间2:8547 s:7888890 运行时间1:11484 s:7888890 运行时间2:8547 s:7888890
关于您的基准测试的两点意见:Java是一个复杂的环境,它具有即时编译和垃圾收集等功能,因此为了进行公平的比较,每当我运行基准测试时,我总是:(a)将两个测试放在一个循环中,按顺序运行5到10次。通常,第二次通过循环的运行时与第一次完全不同。(b)在每次“方法”之后,我都执行System.gc()来尝试触发垃圾收集。否则,第一种方法可能会生成一堆对象,但不足以强制垃圾收集,然后第二种方法会创建几个对象,堆耗尽,垃圾收集运行。然后,第二种方法因捡拾第一种方法留下的垃圾而“收费”。太不公平了 这就是说,在这个例子中,上述两项都没有显著的区别 不管有没有这些修改,我得到的结果和你的完全不同。当我运行这个时,是的,toString方法给出了6400到6600毫秒的运行时间,而log方法给出了20000到20400毫秒的运行时间。而不是稍微快一点,日志方法对我来说慢了3倍 请注意,这两种方法涉及非常不同的成本,因此这并不完全令人震惊:toString方法将创建大量必须清理的临时对象,而log方法需要更密集的计算。因此,可能不同之处在于,在内存较少的机器上,toString需要更多的垃圾收集循环,而在处理器较慢的机器上,额外的日志计算将更加痛苦 我还尝试了第三种方法。我写了这个小函数:
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;
}
这在1600到1900毫秒之间运行——不到我机器上toString方法的1/3,和log方法的1/10
如果你有一个广泛的数字范围,你可以通过开始除以1000或1000000来减少循环次数,从而进一步加快速度。我没有玩过这个。最快的方法:分而治之 假设您的范围是0到MAX_INT,那么您有1到10个数字。您可以使用“分而治之”来接近此间隔,每个输入最多可进行4次比较。首先,通过一次比较将[1..10]划分为[1..5]和[6..10],然后使用一次比较将每个长度为5的间隔划分为一个长度为3的间隔和一个长度为2的间隔。长度2间隔需要再进行一次比较(总共3次比较),长度3间隔可分为长度1间隔(解决方案)和长度2间隔。所以,你需要3到4次比较 没有除法,没有浮点运算,没有昂贵的对数,只有整数比较 代码(长但快):
if(n<100000){
//5或更少
如果(n<100){
//1或2
如果(n<10)
返回1;
其他的
返回2;
}否则{
//3或4或5
如果(n<1000)
返回3;
否则{
//4或5
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;
}
}
}
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;
}
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;
}
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;
}
}
}
}
}
public static int getSize(long number) {
int count = 0;
while (number > 0) {
count += 1;
number = (number / 10);
}
return count;
}
private static int length = 0;
public static int length(int n) {
length++;
if((n / 10) < 10) {
length++;
} else {
length(n / 10);
}
return length;
}
public class long_length {
long x,l=1,n;
for (n=10;n<x;n*=10){
if (x/n!=0){
l++;
}
}
System.out.print(l);
}
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;
}
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;
}
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)));
}
ArrayList<Integer> a=new ArrayList<>();
while(number > 0)
{
remainder = num % 10;
a.add(remainder);
number = number / 10;
}
int m=a.size();
public int numLength(int n) {
for (int length = 1; n % Math.pow(10, length) != n; length++) {}
return length;
}
int num = 02300;
int count = 0;
while(num>0){
if(num == 0) break;
num=num/10;
count++;
}
System.out.println(count);
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;
}
}
public class IntegerLenght {
public static byte calculateIntLenght(int num) {
for(IntegerLength v : IntegerLength.values()) {
if(num < v.getValue()){
return v.getLenght();
}
}
return 0;
}
}
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);
}
}
/**
* 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;
}
/**
* 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;
}
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);
public static int intLength(int num){
String n = Integer.toString(num);
int newNum = n.length();
return newNum;
}
int get_int_lenght(current_lenght, value)
{
if (value / 10 < 10)
return (current_lenght + 1);
return (get_int_lenght(current_lenght + 1, value))
}
long n = 99999999999999999L;
// correct answer: 17
int numberOfDigits = String.valueOf(n).length();
// incorrect answer: 18
int wrongNumberOfDigits = (int) (Math.log10(n) + 1);
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+"]");
}
int nDigits = Math.floor(Math.log10(Math.abs(the_integer))) + 1;
int nDigits = floor(log10(abs(the_integer))) + 1;
int length = ("" + n).length();
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;
}
}
}
private static int getLength(long num) {
int count = 1;
while (num >= 10) {
num = num / 10;
count++;
}
return count;
}
public static int getNumberOfDigits(int input) {
int numOfDigits = 1;
int base = 1;
while (input >= base * 10) {
base = base * 10;
numOfDigits++;
}
return numOfDigits;
}