56

I have a number assigned to a variable, like that:

var myVar = 1234;

Now I want to get the second digit (2 in this case) from that number without converting it to a string first. Is that possible?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
user1856596
  • 7,027
  • 10
  • 41
  • 63

14 Answers14

93

So you want to get the second digit from the decimal writing of a number.

The simplest and most logical solution is to convert it to a string :

var digit = (''+myVar)[1];

or

var digit = myVar.toString()[1];

If you don't want to do it the easy way, or if you want a more efficient solution, you can do that :

var l = Math.pow(10, Math.floor(Math.log(myVar)/Math.log(10))-1);
var b = Math.floor(myVar/l);
var digit = b-Math.floor(b/10)*10;

Demonstration

For people interested in performances, I made a jsperf. For random numbers using the log as I do is by far the fastest solution.

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • 15
    The question is how to do it **without** converting to a string first. Perhaps the OP wants to learn how to do the math. This doesn't answer the question. – John Kugelman Dec 19 '12 at 15:38
  • 9
    @JohnKugelman SO is about **practical questions**, not puzzles. That's why I first answered it with the simple solution. Now I edited with a solution which doesn't involve a conversion to string. – Denys Séguret Dec 19 '12 at 15:40
  • 8
    Learning how to manipulate integers is quite practical. How do you think integers are converted to strings in the first place? Also your mathematical solution yields `7` for 123456789. – John Kugelman Dec 19 '12 at 15:45
  • @JohnKugelman I made an answer for numbers with more digits. See edit. – Denys Séguret Dec 19 '12 at 15:58
  • 1
    Latest version of chrome(59), (''+n)[1] seems to be faster... weird – JellyKid Jul 07 '17 at 18:23
48

1st digit of number from right → number % 10 = Math.floor((number / 1) % 10)

1234 % 10; // 4
Math.floor((1234 / 1) % 10); // 4

2nd digit of number from right → Math.floor((number / 10) % 10)

Math.floor((1234 / 10) % 10); // 3

3rd digit of number from right → Math.floor((number / 100) % 10)

Math.floor((1234 / 100) % 10); // 2

nth digit of number from right → Math.floor((number / 10^n-1) % 10)

function getDigit(number, n) {
  return Math.floor((number / Math.pow(10, n - 1)) % 10);
}

number of digits in a number → Math.max(Math.floor(Math.log10(Math.abs(number))), 0) + 1 Credit to: https://stackoverflow.com/a/28203456/6917157

function getDigitCount(number) {
  return Math.max(Math.floor(Math.log10(Math.abs(number))), 0) + 1;
}

nth digit of number from left or right

function getDigit(number, n, fromLeft) {
  const location = fromLeft ? getDigitCount(number) + 1 - n : n;
  return Math.floor((number / Math.pow(10, location - 1)) % 10);
}
vsync
  • 118,978
  • 58
  • 307
  • 400
Gerges Beshay
  • 481
  • 4
  • 4
  • 1
    You answer is correct, but doesn't answer the question, because it asks about 2nd number from the left, not right :) – user2857033 Feb 01 '17 at 04:34
  • Your answer works for me. I want to get total digits of a number and check each digit is greater than a constant. – Suhas Bhosale Mar 24 '20 at 10:31
4

Get rid of the trailing digits by dividing the number with 10 till the number is less than 100, in a loop. Then perform a modulo with 10 to get the second digit.

if (x > 9) {
    while (x > 99) {
        x = (x / 10) | 0;  // Use bitwise '|' operator to force integer result.
    }
    secondDigit = x % 10;
}
else {
    // Handle the cases where x has only one digit.
}
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Vikdor
  • 23,934
  • 10
  • 61
  • 84
  • 4
    you're going to write another if statement for every digit added? have fun with that. – jbabey Dec 19 '12 at 15:38
  • 2
    @jbabey, sorry, I didn't understand what you meant by "if statement for every digit"? – Vikdor Dec 19 '12 at 16:44
  • 2
    @jbabey, I still don't think your comment is relevant even to the first version of this response: http://stackoverflow.com/revisions/dbc88f52-49bf-475f-8e0a-2ab7133cc07c/view-source. – Vikdor Dec 20 '12 at 01:25
  • 1
    There are still two (fixable) bugs in this solution : it doesn't work for negative numbers and it gives wrong digits for midly big numbers (try `9999999999|0` in the console to see why). – Denys Séguret May 27 '14 at 08:00
4

A "number" is one thing.

The representation of that number (e.g. the base-10 string "1234") is another thing.

If you want a particular digit in a decimal string ... then your best bet is to get it from a string :)

Q: You're aware that there are pitfalls with integer arithmetic in Javascript, correct?

Q: Why is it so important to not use a string? Is this a homework assignment? An interview question?

paulsm4
  • 114,292
  • 17
  • 138
  • 190
3

function getNthDigit(val, n){
    //Remove all digits larger than nth
    var modVal = val % Math.pow(10,n);

    //Remove all digits less than nth
    return Math.floor(modVal / Math.pow(10,n-1));
}

// tests
[
  0, 
  1, 
  123, 
  123456789, 
  0.1, 
  0.001
].map(v => 
  console.log([
      getNthDigit(v, 1),
      getNthDigit(v, 2),
      getNthDigit(v, 3)
    ]
  ) 
);
vsync
  • 118,978
  • 58
  • 307
  • 400
mutenka
  • 59
  • 4
  • 1
    Please edit with more information. Code-only and "try this" answers are discouraged, because they contain no searchable content, and don't explain why someone should "try this". – abarisone Sep 08 '16 at 07:09
  • Maybe the answer's format ain't the best, but you do deserve credit for the test cases. – Artur Apr 21 '20 at 22:40
3

You know, I get that the question asks for how to do it without a number, but the title "JavaScript: Get the second digit from a number?" means a lot of people will find this answer when looking for a way to get a specific digit, period.

I'm not bashing the original question asker, I'm sure he/she had their reasons, but from a search practicality standpoint I think it's worth adding an answer here that does convert the number to a string and back because, if nothing else, it's a much more terse and easy to understand way of going about it.

let digit = Number((n).toString().split('').slice(1,1))

// e.g.
let digit = Number((1234).toString().split('').slice(1,1)) // outputs 2

Getting the digit without the string conversion is great, but when you're trying to write clear and concise code that other people and future you can look at really quick and fully understand, I think a quick string conversion one liner is a better way of doing it.

Chris Schmitz
  • 20,160
  • 30
  • 81
  • 137
3

This is how I would do with recursion

function getDigits(n, arr=[]) {
   arr.push(n % 10)

   if (n < 10) {
     return arr.reverse()
   }
   return getDigits(Math.floor(n/10),arr)
  }

const arr = getDigits(myVar)
console.log(arr[2])
bdemirka
  • 817
  • 2
  • 9
  • 24
1

Just a simple idea to get back any charter from a number as a string or int:

const myVar = 1234;
String(myVar).charAt(1)
//"2"
parseInt(String(myVar).charAt(1))
//2
Jamie Hutber
  • 26,790
  • 46
  • 179
  • 291
0

I don’t know why you need this logic, but following logic will get you the second number

<script type="text/javascript">
    var myVal = 58445456;
    var var1 = new Number(myVal.toPrecision(1));
    var var2 = new Number(myVal.toPrecision(2));     
    var rem;
    rem = var1 - var2;
    var multi = 0.1;
    var oldvalue;
    while (rem > 10) {
        oldvalue = rem;
        rem = rem * multi;
        rem = rem.toFixed();           
    }
    alert(10-rem);       
</script>
René Höhle
  • 26,716
  • 22
  • 73
  • 82
Raghav
  • 9
  • 1
0

function getDigit(number, indexFromRight) { 
            var maxNumber = 9
            for (var i = 0; i < indexFromRight - 2; i++) {
                maxNumber = maxNumber * 10 + 9
            }
            if (number > maxNumber) {
                number = number / Math.pow(10, indexFromRight - 1) | 0
                return number % 10
            } else
                return 0
        }
Coaxial
  • 133
  • 1
  • 10
0

you can use this function index = 0 will give you the first digit from the right (the ones) index = 1 will give you the second digit from the right (the tens)

and so on

const getDigit = (num, index) => {
    

    if(index === 0) {
        return num % 10;
    }

    let result = undefined;

    for(let i = 1; i <= index; i++) {
        num -= num % 10;
        num /= 10;
        result = num % 10;
    }

    return result;

}

for Example:

getDigit(125, 0)   // returns 5
gitDigit(125, 1)   // returns 2
gitDigit(125, 2)   // returns 1
gitDigit(125, 3)   // returns 0
0
function left(num) {
    let newarr = [];
    let numstring = num.split('[a-z]').join();
    //return numstring;
    const regex = /[0-9]/g;
    const found = numstring.match(regex);
   // return found;
    for(i=0; i<found.length; i++){
        return found[i];
    }
    } 
//}
console.log(left("TrAdE2W1n95!"))
S Gabale
  • 1
  • 3
0
function getNthDigit(n, number){
    return ((number % Math.pow(10,n)) - (number % Math.pow(10,n-1))) / Math.pow(10,n-1);
}

Explanation (Number: 987654321, n: 5):
a = (number % Math.pow(10,n)) - Remove digits above => 54321
b = (number % Math.pow(10,n-1)) - Extract digits below => 4321
a - b => 50000
(a - b) / 10^(5-1) = (a - b) / 10000 => 5

-4
var newVar = myVar;
while (newVar > 100) {
    newVar /= 10;
}

if (newVar > 0 && newVar < 10) {
   newVar = newVar;
}

else if (newVar >= 10 && newVar < 20) {
   newVar -= 10;
}

else if (newVar >= 20 && newVar < 30) {
   newVar -= 20;
}

else if (newVar >= 30 && newVar < 40) {
   newVar -= 30;
}

else if (newVar >= 40 && newVar < 50) {
   newVar -= 40;
}

else if (newVar >= 50 && newVar < 60) {
   newVar -= 50;
}

else if (newVar >= 60 && newVar < 70) {
   newVar -= 60;
}

else if (newVar >= 70 && newVar < 80) {
   newVar -= 70;
}

else if (newVar >= 80 && newVar < 90) {
   newVar -= 80;
}

else if (newVar >= 90 && newVar < 100) {
   newVar -= 90;
}

else {
   newVar = 0;
}

var secondDigit = Math.floor(newVar);

That's how I'd do it :)

And here's a JSFiddle showing it works :) http://jsfiddle.net/Cuytd/

This is also assuming that your original number is always greater than 9... If it's not always greater than 9 then I guess you wouldn't be asking this question ;)

simonthumper
  • 1,834
  • 2
  • 22
  • 44