从长变量中获取第二个数字

时间:2017-12-26 08:11:34

标签: java long-integer

我正在尝试从长变量中获取第二个数字。

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,但是当循环结束时firstDigit49。 有点困惑的原因。

11 个答案:

答案 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而不是数字的原因。