有没有比这个方法更整洁的方法来获取int的长度?
int length = String.valueOf(1000).length();
请定义int的长度。
我只是好奇为什么你需要整型的长度,这可能会影响我的答案。
我想他想数一数数字。
是的,我想要数字。与示例相同,但不将其转换为字符串
人们给你的答案是正确的……他们给你int的长度,而不把它转换成字符串……但是为什么不把它转换成字符串呢?这是速度问题吗?如果是这样,我不相信这些方法会更快……您可能需要做一些测试(或者决定它是否重要)。
的确!芬斯特:你说的是"一个数字的字符串表示的长度"。为了更清楚地说明这个问题并不重要,请尝试"int length=integer.toString(1000,10).length();"并与"int length=integer.toString(1000,16).length();"进行比较,第一个数字是用十进制表示1000的位数,第二个数字是用十六进制表示1000的字符数。字符,因为十六进制包括0-9和a-f。是否尝试基于此格式化某些内容?如果是,那么查看string.format(字符串格式、对象参数…)
@ptomli十六进制数字仍然是数字,只是在不同的基系统中。
@ptomli当然,但在integer.tostring函数和一般会话中,decimal都是默认值。当银行告诉我,"把你支票的金额写在这个框里"时,我不会问他们我应该用十进制、十六进制还是八进制来写。除非上下文另有规定或要求,否则我们假定为十进制。
您的基于字符串的解决方案是完全正常的,没有什么"不整洁"的地方。你必须认识到,在数学上,数字没有长度,也没有数字。长度和数字都是特定基数(即字符串)中数字的物理表示形式的属性。
基于对数的解决方案与基于字符串的解决方案在内部执行的操作(某些操作)相同,而且可能更快(无显著意义),因为它只生成长度并忽略数字。但实际上我并不认为它在意图上更清晰——这是最重要的因素。
+1用于在选择解决问题的方法时考虑代码的意图
数据点:在我的机器上,日志方法的运行速度似乎是字符串长度方法的两倍。如果方法经常被调用,或者在代码的时间关键部分被调用,我不会称之为无关紧要的。
请看下面我的基准单元测试(wich也可能有缺陷,我不是基准专家)。在大量的运行中(1000000次),我的机器的速度是11秒到8秒,几乎是速度的两倍。
@佩金斯。过早优化。你知道这个秘密。
正如@michaelborgwardt所解释的。组成一个数字的数字只作为一个值的文本表示存在,这个值只存在于逻辑中。你可以看到的数字不是值本身,而是一组不同的文本字符,这些字符遵循一定的逻辑,代表一个完全符合逻辑的值,并且在物理上是无效的。
一些(非常晚的)附加:它可能不能正确地用于负值,这取决于您是否希望"-"是一个数字。不过,添加EDOCX1[2]可以解决这个问题。
对数是你的朋友:
int n = 1000;
int length = (int)(Math.log10(n)+1);
注:仅适用于n>0。
这是比使用我的变体更快还是更好?
+你打了我一秒钟,你的回答是对的,我的回答有点偏离。但是请注意,编译器会因为缺少int的强制转换而抱怨
正如其他人所说,您应该尝试使用这两种方法进行速度测试。我自己也没试过。
@芬斯特:事实上可能。您需要分配char数组和非平凡的计算(除法/余数),以便生成字符串表示。另外:之后字符串会被丢弃,所以所有这些只是为了计算长度…
我认为这是非常明确的打算。
@汤姆,你为什么认为它很贵?有人可能会假设数学协处理器会执行它,所以它可能接近于加法的速度。即使Java现在不使用协处理器,这是一个很好的假设,它可能…(我们会忽略你更不受教育的暗示,Java是缓慢的,因为你可能对证据不感兴趣,或者如果你去射击游戏。
作品。。。除非您要检查的值为0,否则会产生奇数结果(-2147483647)。math.log10 api:"如果参数为正零或负零,则结果为负无穷大。"
+1表示一个不涉及对象内存分配的方法,这是最大限度地重用以避免GC集合的必要条件。
最快的方法:分而治之。
假设您的范围是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 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;
}
}
}
基准测试(在JVM预热之后)-请参阅下面的代码以了解基准测试是如何运行的:
基线方法(带string.length):2145MS
log10方法:711ms=3.02次比基线快
重复除法:2797ms=0.77次比基线快
分而治之:74ms=28.99比基线快几倍
完整代码:
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 faster than baseline");
c = new Chronometer(true);
allMethod3();
c.stop();
System.out.println(c +" =" + StringTools.formatDouble((double)baseline / c.getValue() ,"0.00") +" times faster than baseline");
c = new Chronometer(true);
allMethod4();
c.stop();
System.out.println(c +" =" + StringTools.formatDouble((double)baseline / c.getValue() ,"0.00") +" times faster than 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;
}
号
同样,基准:
基线方法(带string.length):2145MS
log10方法:711ms=3.02次比基线快
重复除法:2797ms=0.77次比基线快
分而治之:74ms=28.99比基线快几倍
编辑:在我写了基准之后,我从Java 6中偷偷地进入了整数。ToStand,我发现它使用:
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;
}
我把它与我的分而治之的解决方案作了比较:
分而治之:104ms
Java 6解决方案——迭代与比较:406MS
我的大约快4倍。
这看起来不错。你可以用这个写得更紧凑一点?:操作员获得更多认可
谈提前优化:D
我喜欢!如果是elsese,那么用开关块代替嵌套的怎么样?
我没有意识到所有这些if-else语句都比将int转换成字符串然后调用.length快得多。+ 1
使用三元运算符,可以将其减少到101个字符: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。
我从来没有意识到我会写一本书来截断一个包含远程组成它的项目数的字符串。我想我会损失300美元来节省400行代码…
@DodgycodeException哇,很好的捕获。删除我使用科学符号的评论,因为它不正确。
Java 8仍然使用整数实现。
关于你的基准的两个评论:Java是一个复杂的环境,什么是及时编译和垃圾收集等等,所以为了得到公平的比较,每当我运行一个基准时,我总是:(a)将两个测试包围在一个循环中,这些循环以5或10次顺序运行它们。通常,第二次循环传递的运行时与第一次循环有很大的不同。(b)在每个"方法"之后,我都会执行system.gc()来尝试触发垃圾收集。否则,第一种方法可能会生成一堆对象,但不足以强制进行垃圾收集,然后第二种方法创建一些对象,堆耗尽,垃圾收集运行。然后,第二种方法被"充电"以拾起第一种方法留下的垃圾。非常不公平!
也就是说,在这个例子中,上述两个都没有显著的区别。
不管有没有这些修改,我得到的结果与你完全不同。当我运行这个时,是的,ToString方法给出了6400到6600毫秒的运行时间,而Log方法给出了20000到20400毫秒的运行时间。对于我来说,日志方法不是稍微快一点,而是慢三倍。
请注意,这两种方法涉及的成本非常不同,因此这并不完全令人震惊: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来进一步加快速度,从而减少通过循环的次数。我没玩过。
你试过改变输入吗?Hotspot虚拟机可以优化此图,否则会导致错误的基准,因为它每次都返回相同的预计算内容。
使用Java
int nDigits = Math.floor(Math.log10(Math.abs(the_integer))) + 1;
一开始使用import java.lang.Math.*;。
使用C
int nDigits = floor(log10(abs(the_integer))) + 1;
。
一开始使用inclue math.h。
仅供参考,如果the_integer是0,将导致无穷大,所以检查一下。
由于整数以10为底的位数仅为1+截断(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);
}
}
号
编辑是因为我上次编辑修复了代码示例,但没有修复描述。
酷。但我认为它需要abs(数字),而且"0"也是特殊情况吗?
对。如果你需要解释这个符号,你需要做一些像1+(int)math.floor(math.log10(math.abs(number)))+(number<0)?1:0)
Math.floor有点多余,不是吗?投注到EDOCX1[1]将使其四舍五入。
还不能发表评论,所以我将作为单独的答案发表。
基于对数的解决方案无法计算非常大的长整数的正确位数,例如:
long n = 99999999999999999L;
// correct answer: 17
int numberOfDigits = String.valueOf(n).length();
// incorrect answer: 18
int wrongNumberOfDigits = (int) (Math.log10(n) + 1);
。
基于对数的解计算大整数中不正确的位数
尝试(int)(math.log10(n+j)),而j是10-(n-n/10*10)。
这是真的!数字超过14的数字表示这个问题…
Marian的解决方案适用于长类型数字(最多9223372036854775807),以防有人想要复制和粘贴它。在这个程序中,我为多达10000个数字编写的这个更可能,所以我为它们做了一个特定的分支。无论如何,这不会有什么显著的区别。
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;
}
}
}
}
}
。
这个问题的标题应该改为"获取int/long中位数的方法吗?"(并添加了"long"标签)
我能试试吗?;)
基于Dirk的解决方案
final int digits = number==0?1:(1 + (int)Math.floor(Math.log10(Math.abs(number))));
简单的旧数学怎么样?除以10直到0。
public static int getSize(long number) {
int count = 0;
while (number > 0) {
count += 1;
number = (number / 10);
}
return count;
}
你测试过了吗?你知道,即使对人类来说,这很难理解,但对机器的"思维方式"来说,它并不是真正的工作方式,对吧?---让我提出一个建议:创建一个200万个数字的数组,最好是Long.MAX_VALUE,这是代码最复杂的情况,并使用System.nanoTime()对另一个解决方案最复杂的情况进行计时测试。++实际上,使用一个随机数发生器填充的数组来尝试它,该数组设置为0到Long.MAX_VALUE的范围,仅仅对于"平均复杂度"测试+,您可能会发现结果……非常令人震惊。
@这对零或负的情况并不适用,但这只是一个小问题。我认为这个原则是正确的。你所指的"令人震惊"的结果是什么?
让我们说一下,电脑……嗯……他们不喜欢分裂。在需要处理大量"队列"的情况下,每个处理过的数字中的每个数字都需要一个除法……好吧……事情"开始变得非常慢,非常快"…如果你理解我的意思……---这就是为什么你在这里看到许多答案是使用基于测试的代码,并与使用"if"而不是除法的每个十进制数字进行比较:如果速度不快,那么不管最坏的情况如何,至少它都能保持大部分的速度。---在大数上使用除法和对数之间做一个测试…
@你在说什么?对于一个int,,这个循环最多执行11次。你有证据支持你的断言吗?
@从硬件的角度来看,划分是一个迭代过程。我所知道的最快的除法是radix4,每次迭代生成4位;因此32位除法至少需要8次迭代。例如,乘法可以并行进行,也可以分解为更简单的乘法;可以分解为位级(只需要5个操作),也可以部分分解并在末尾加上查找表(经典的大小与速度权衡)。这不仅仅是关于"多少次迭代";划分的问题在于"每个迭代在硬件级别意味着/做什么"
玛丽安的溶液,现在是三元:
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)));
}
因为我们可以。
这有点难懂。可以添加一些空格和/或换行符。
但该死的是便携式的!
另一个字符串方法。短而甜-适用于任何整数n。
int length = ("" + n).length();
好奇的是,我试着把它作为基准…
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);
}
}
。
结果是:
Run time 1: 6765
s: 400000000
Run time 2: 6000
s: 400000000
现在我想知道我的基准测试是否真的有意义,但是我确实在基准测试的多次运行中得到了一致的结果(毫秒内的变化)。:)尝试优化这一点似乎毫无用处…
编辑:根据ptomli的评论,我在上面的代码中用"i"替换了"number",并在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
。
仅仅为了好玩,一个数字值的分布有什么区别,从0到1万亿?:)
@托姆利:很好的接球
这个递归方法怎么样?
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
if (x/n!=0){
l++;
}
}
System.out.print(l);
}
。
一个非常简单的解决方案:
public int numLength(int n) {
for (int length = 1; n % Math.pow(10, length) != n; length++) {}
return length;
}
号
我不会用一个简单的空体来表示一行一循环。也不能用10的幂来看看你是否能得到同样的结果(你不能用比较吗?).
与设计(基于问题)。这是分而治之的交替。我们首先定义一个枚举(考虑到它只针对无符号int)。
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;
}
}
号
此解决方案的运行时间与分治方法相同。
分而治之的办法是从中间开始,把剩下的搜索区域一分为二。这是一个线性运行时间。但仅仅9个比较就没关系了。但如果num>=Nine.getValue()的话,这会不会一团糟?
或者您可以检查数字是否大于或小于所需数字的长度。
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);
}
}
号
}
我不明白。你好像在回答另一个问题。
我还没有看到基于乘法的解。对数、除数和基于字符串的解决方案将变得相当难对付数百万个测试用例,因此这里有一个针对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;
}
在以10为基数的情况下,这是有效的,因为n基本上与9,99,999…因为最小值是9,90,900…n减去9,90,900…
不幸的是,由于溢出,仅通过替换int的每个实例,它不能移植到long。另一方面,它同样适用于2垒和10垒(但其他大多数垒都严重失败)。您需要一个溢出点的查找表(或一个除法测试…电子战)
/**
* 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;
}
号
我们可以使用递归循环来实现这一点
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+"]");
}
。
人们之所以想这样做,主要是因为他/她想"呈现"它,这意味着它最终需要"以另一种方式"显式或隐式地"扭曲"(或以另一种方式转换),然后才能呈现(例如打印)。
如果是这种情况,那么只需尝试使必要的"to字符串"显式并计算位。
int num = 02300;
int count = 0;
while(num>0){
if(num == 0) break;
num=num/10;
count++;
}
System.out.println(count);
号
两年前,Sinista首次发布了"除以10"的解决方案。
简单的递归方式
int get_int_lenght(current_lenght, value)
{
if (value / 10 < 10)
return (current_lenght + 1);
return (get_int_lenght(current_lenght + 1, value))
}
未试验过
您可能应该测试它(并确保它是有效的Java并正确格式化)。但绝地杜拉3年前发布了一个递归的"除以10"方法。
以下是我制作的一个非常简单的方法,适用于任何数字:
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;
}
它的工作方式是使用数字计数器变量,即10=1位数的空格。例如,1=十分之一=>1位空格。因此,如果你有int number = 103342;,你会得到6个,因为这相当于0.000001个空格。另外,是否有人对numberCounter有更好的变量名?我想不出比这更好的了。
编辑:只是想一个更好的解释。实际上,这个while循环所做的就是让它,所以你把你的数字除以10,直到它小于1。本质上,当你把某个数除以10时,你会把它移回一个数字空间,所以你只需要简单地把它除以10,直到你的数字的位数小于1。
下面是另一个可以用十进制计算数字的版本:
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;
}
。
你可以用连续十除的数字:
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);
三年前,Sinista首次发布了"除以10"的方法。我能想到的唯一原因就是你投了反对票。
输入数字并创建一个Arraylist,while循环将所有数字记录到Arraylist中。然后我们可以取出数组的大小,即您输入的整数值的长度。
ArrayList a=new ArrayList<>();
while(number > 0)
{
remainder = num % 10;
a.add(remainder);
number = number / 10;
}
int m=a.size();
。
但你不需要数组列表或数字。
尝试将int转换为字符串,然后获取字符串的长度。这应该得到int的长度。
public static int intLength(int num){
String n = Integer.toString(num);
int newNum = n.length();
return newNum;
}
。
这完全等同于原始代码。当number为负时,将丢失。