我正在尝试从长变量中获取第二个数字。
long mi = 110000000;
int firstDigit = 0;
String numStr = Long.toString(mi);
for (int i = 0; i < numStr.length(); i++) {
System.out.println("" + i + " " + numStr.charAt(i));
firstDigit = numStr.charAt(1);
}
当我在控制台上打印firstDigit = numStr.charAt(1)
时。我得到的是1
,但是当循环结束时firstDigit
有49
。
有点困惑的原因。
答案 0 :(得分:14)
因为49是char&#39; 1&#39;的ASCII值。
所以你不应该直接给int赋一个char。
你不需要在这里使用charAt(1)
来保持当前值的循环。
int number = numStr.charAt(1) - '0'; // substracting ASCII start value
上述声明内部的工作方式类似于49-48,并为您提供1。
如果您认为这是混乱的,正如其他人所说的那样使用Character.getNumericValue();
或者,虽然我不喜欢""+
黑客,但下面应该有效
int secondDigit = Integer.parseInt("" + String.valueOf(mi).charAt(1));
答案 1 :(得分:10)
您感到困惑,因为49是整数1的ASCII值。因此您可以将字符解析为整数,然后您可以看到整数值。
Integer.parseInt(String.valueOf(mi).charAt(1)):
答案 2 :(得分:5)
你可能正在寻找Character.getNumericValue(...)
即
firstDigit = Character.getNumericValue(numStr.charAt(1));
否则,因为变量firstDigit
的类型为int
,这意味着您要分配的ASCII representation of the character '1'为49而不是指定索引处的整数。
另请注意,由于您只对特定数字感兴趣,因此无需将语句firstDigit = numStr.charAt(1);
放在循环中。
相反,只需在循环外执行以下操作。
int number = Character.getNumericValue(numStr.charAt(1));
答案 3 :(得分:3)
您只需要将firstDigit定义为char类型变量,因此将打印为字符。 因为你定义为int变量,它的值是char&#39; 1&#39;:49的ASCII值。这就是你得49而不是1的原因。
答案 4 :(得分:3)
答案Integer.parseInt(String.valueOf(mi).charAt(1)+"");
是正确的。
但是,如果我们想在我们的计划中考虑性能,我们需要一些改进。
我们必须耗费时间,Integer.parseInt()
和String.valueOf()
。自定义方法总是比Integer.parseInt()
和String.valueOf()
快得多。见simple benchmarks。
因此,高性能解决方案如下所示:
int y=0;
while (mi>10)
{
y=(int) (mi%10);
mi=mi/10;
}
System.out.println("Answer is: " + y);
测试它:
long mi=4642345432634278834L;
int y=0;
long start = System.nanoTime();
//first solution
//y=Integer.parseInt(String.valueOf(mi).charAt(1)+"");
//seconf solution
while (mi>10)
{
y=(int) (mi%10);
mi=mi/10;
}
long finish = System.nanoTime();
long d = finish - start;
System.out.println("Answer is: " + y + " , Used time: " + d);
//about 821 to 1232 for while in 10 runs
//about 61225 to 76687 for parseInt in 10 runs
答案 5 :(得分:3)
使用字符串操作来处理数字几乎总是错误的方法。
要获得第二个数字,请使用以下内容;
int digitnum = 2;
int length = (int)Math.log10(mi));
int digit = (int)((mi/Math.pow(base,length-digitnum+1))%base);
如果你想要一个不同于第二个更改数字的数字。
为避免浮点数的不确定性,您可以使用整数数学库,例如guavas IntMath
答案 6 :(得分:2)
我们来看看
System.out.println(numStr.charAt(1));
firstDigit = numStr.charAt(1);
System.out.println(firstDigit);
结果与你得到的结果不一样
1
49
这是因为 firstDigit 是 int 。将其更改为 char ,您将获得预期的结果
答案 7 :(得分:1)
你也可以这样做,
firstDigit = Integer.parseInt( numStr.charAt(1)+"");
所以它会从长号打印第二个数字。
答案 8 :(得分:1)
有些事情尚未提及:
整数数据类型的第二个数字是未定义,如果长数是0-9(不,它不是零。整数没有小数位,这只适用于浮点数点数。即使这样,你必须为NaN或无穷大值返回 undefined 。在这种情况下,你应该返回一个像-1表示没有第二个数字。
使用log10获取特定数字看起来很优雅,但它们是1.数字上最昂贵的函数之一,而且2.在边缘情况下经常给出不正确的结果。我稍后会给出一些反例。
可以进一步提高绩效:
public static int getSecondDigit(long value) {
long tmp = value >= 0 ? value : -value;
if (tmp < 10) {
return -1;
}
long bigNumber = 1000000000000000000L;
boolean isBig = value >= bigNumber;
long decrement = isBig ? 100000000000000000L : 1;
long firstDigit = isBig ? bigNumber : 10;
int result = 0;
if (!isBig) {
long test = 100;
while (true) {
if (test > value) {
break;
}
decrement = firstDigit;
firstDigit = test;
test *= 10;
}
}
// Remove first
while (tmp >= firstDigit) {
tmp -= firstDigit;
}
// Count second
while (tmp >= decrement) {
tmp -= decrement;
result++;
}
return result;
}
比较: 1 000 000随机长片
String.valueOf()/ Character.getNumericValue():106 ms
由Taemyr制造的Log / Pow:151毫秒
Div10 by @ Gholamali-Irani:45 ms
例程高于:30毫秒
这不是结束,查找表可以更快 递减1/2/4/8,10 / 20/40/80并避免使用乘法。
答案 9 :(得分:0)
尝试这个以获得长期
的第二个字符mi.toString().charAt(1);
答案 10 :(得分:0)
如何获取ASCII码
int ascii = 'A';
int ascii = 'a';
因此,如果将字符分配给整数,则整数将保持该字符的ASCII
值。在这里我明确地给出了值,在你的代码中你调用了一个返回一个字符的方法,这就是你得到ASCII
而不是数字的原因。