Finding the leading digit(s) in any number

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
4
down vote

favorite
1












I am somewhat perplexed by this (presumably very simple) issue.



Simply, I am trying to find the leading digit(s) in any number (related question). Here is some nice python code (from this question):



import math

def first_n_digits(num, n):
# where n is the number of leading digits of interest
return num // 10 ** (int(math.log(num, 10)) - n + 1)


This works great for most numbers, for example:



>>> first_n_digits(123456, 1)
1
>>> first_n_digits(123456, 2)
12
>>> first_n_digits(123456, 3)
123
>>> first_n_digits(123456, 4)
1234
>>> first_n_digits(123456, 5)
12345
>>> first_n_digits(123456, 6)
123456


The problem is this does not work for num=1000 and n=1.



first_n_digits(1000, 1)
10


This issue does not appear when num = 10,100,10000,100000. Just num = 1000.



How can one deal with this edge case? I have not found any others so far. I expect there to be some very simple solution which I have overlooked.










share|cite|improve this question





















  • Could you take log10 of $n+1/2$ to avoid the tiny errors
    – Empy2
    56 mins ago















up vote
4
down vote

favorite
1












I am somewhat perplexed by this (presumably very simple) issue.



Simply, I am trying to find the leading digit(s) in any number (related question). Here is some nice python code (from this question):



import math

def first_n_digits(num, n):
# where n is the number of leading digits of interest
return num // 10 ** (int(math.log(num, 10)) - n + 1)


This works great for most numbers, for example:



>>> first_n_digits(123456, 1)
1
>>> first_n_digits(123456, 2)
12
>>> first_n_digits(123456, 3)
123
>>> first_n_digits(123456, 4)
1234
>>> first_n_digits(123456, 5)
12345
>>> first_n_digits(123456, 6)
123456


The problem is this does not work for num=1000 and n=1.



first_n_digits(1000, 1)
10


This issue does not appear when num = 10,100,10000,100000. Just num = 1000.



How can one deal with this edge case? I have not found any others so far. I expect there to be some very simple solution which I have overlooked.










share|cite|improve this question





















  • Could you take log10 of $n+1/2$ to avoid the tiny errors
    – Empy2
    56 mins ago













up vote
4
down vote

favorite
1









up vote
4
down vote

favorite
1






1





I am somewhat perplexed by this (presumably very simple) issue.



Simply, I am trying to find the leading digit(s) in any number (related question). Here is some nice python code (from this question):



import math

def first_n_digits(num, n):
# where n is the number of leading digits of interest
return num // 10 ** (int(math.log(num, 10)) - n + 1)


This works great for most numbers, for example:



>>> first_n_digits(123456, 1)
1
>>> first_n_digits(123456, 2)
12
>>> first_n_digits(123456, 3)
123
>>> first_n_digits(123456, 4)
1234
>>> first_n_digits(123456, 5)
12345
>>> first_n_digits(123456, 6)
123456


The problem is this does not work for num=1000 and n=1.



first_n_digits(1000, 1)
10


This issue does not appear when num = 10,100,10000,100000. Just num = 1000.



How can one deal with this edge case? I have not found any others so far. I expect there to be some very simple solution which I have overlooked.










share|cite|improve this question













I am somewhat perplexed by this (presumably very simple) issue.



Simply, I am trying to find the leading digit(s) in any number (related question). Here is some nice python code (from this question):



import math

def first_n_digits(num, n):
# where n is the number of leading digits of interest
return num // 10 ** (int(math.log(num, 10)) - n + 1)


This works great for most numbers, for example:



>>> first_n_digits(123456, 1)
1
>>> first_n_digits(123456, 2)
12
>>> first_n_digits(123456, 3)
123
>>> first_n_digits(123456, 4)
1234
>>> first_n_digits(123456, 5)
12345
>>> first_n_digits(123456, 6)
123456


The problem is this does not work for num=1000 and n=1.



first_n_digits(1000, 1)
10


This issue does not appear when num = 10,100,10000,100000. Just num = 1000.



How can one deal with this edge case? I have not found any others so far. I expect there to be some very simple solution which I have overlooked.







number-theory elementary-number-theory






share|cite|improve this question













share|cite|improve this question











share|cite|improve this question




share|cite|improve this question










asked 2 hours ago









Astrid

265114




265114











  • Could you take log10 of $n+1/2$ to avoid the tiny errors
    – Empy2
    56 mins ago

















  • Could you take log10 of $n+1/2$ to avoid the tiny errors
    – Empy2
    56 mins ago
















Could you take log10 of $n+1/2$ to avoid the tiny errors
– Empy2
56 mins ago





Could you take log10 of $n+1/2$ to avoid the tiny errors
– Empy2
56 mins ago











3 Answers
3






active

oldest

votes

















up vote
3
down vote



accepted










The problem is simply rounding errors. The operation int when applied to a (positive?) float, rounds the number down to the nearest integer. This works fine if we pretend that the output of math.log is exact, but it is not:



>>> math.log(1000, 10)
2.9999999999999996
>>> int(math.log(1000, 10))
2


There are ways to fix this, e.g. by testing what happens if you compute 10 to the power of the output of this computation, but the more general difficulty is that you can never guarantee that floating point operations will be exact, simply because it's impossible to represent all possible real numbers on a computer.



In fact, the Pythonic way to solve your problem is the entirely robust function (at least for positive integers, and assuming n takes on a reasonable value)



def first_n_digits(num, n):
return int(str(num)[:n])





share|cite|improve this answer




















  • Thanks for that explanation, very helpful. I did know about that solution but was trying to avoid it because it takes a lot more operations. But fair enough, it is very robust, this is true.
    – Astrid
    1 hour ago

















up vote
2
down vote













Python documentation for math.log says




With two arguments, return the logarithm of x to the given base, calculated as log(x)/log(base).




So it is possible that $textmath.log(1000,10)$ is returning a value very slightly less than 3 due to rounding errors, and when you apply int to this you get $2$. Try evaluating $textint(textmath.log(1000,10))$ to see whether this evaluates to $2$ or $3$. (I see Mees de Vries has already done this test).



There is an alternative function in the math module called math.log10:




Return the base-10 logarithm of x. This is usually more accurate than log(x, 10).







share|cite|improve this answer



























    up vote
    -2
    down vote













    The problem is the numerical inaccuracy of Python. Basically when you calculate the logarithm, Python will return 2.999999999... and the int() function will round down to 2. You can use the round()-function instead, e.g. change int(math.log(num, 10)) to round(math.log(num, 10), 1). The second argument tells it to round to integers.



    Alternatively, in Python you can simply transform your integers to strings and back:



    def first_n_digits(num, n):
    return int(str(num)[:n])





    share|cite|improve this answer








    New contributor




    Gemeis is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.

















      Your Answer




      StackExchange.ifUsing("editor", function ()
      return StackExchange.using("mathjaxEditing", function ()
      StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
      StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\(","\\)"]]);
      );
      );
      , "mathjax-editing");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "69"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: false,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      noCode: true, onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













       

      draft saved


      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmath.stackexchange.com%2fquestions%2f2952462%2ffinding-the-leading-digits-in-any-number%23new-answer', 'question_page');

      );

      Post as a guest






























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      3
      down vote



      accepted










      The problem is simply rounding errors. The operation int when applied to a (positive?) float, rounds the number down to the nearest integer. This works fine if we pretend that the output of math.log is exact, but it is not:



      >>> math.log(1000, 10)
      2.9999999999999996
      >>> int(math.log(1000, 10))
      2


      There are ways to fix this, e.g. by testing what happens if you compute 10 to the power of the output of this computation, but the more general difficulty is that you can never guarantee that floating point operations will be exact, simply because it's impossible to represent all possible real numbers on a computer.



      In fact, the Pythonic way to solve your problem is the entirely robust function (at least for positive integers, and assuming n takes on a reasonable value)



      def first_n_digits(num, n):
      return int(str(num)[:n])





      share|cite|improve this answer




















      • Thanks for that explanation, very helpful. I did know about that solution but was trying to avoid it because it takes a lot more operations. But fair enough, it is very robust, this is true.
        – Astrid
        1 hour ago














      up vote
      3
      down vote



      accepted










      The problem is simply rounding errors. The operation int when applied to a (positive?) float, rounds the number down to the nearest integer. This works fine if we pretend that the output of math.log is exact, but it is not:



      >>> math.log(1000, 10)
      2.9999999999999996
      >>> int(math.log(1000, 10))
      2


      There are ways to fix this, e.g. by testing what happens if you compute 10 to the power of the output of this computation, but the more general difficulty is that you can never guarantee that floating point operations will be exact, simply because it's impossible to represent all possible real numbers on a computer.



      In fact, the Pythonic way to solve your problem is the entirely robust function (at least for positive integers, and assuming n takes on a reasonable value)



      def first_n_digits(num, n):
      return int(str(num)[:n])





      share|cite|improve this answer




















      • Thanks for that explanation, very helpful. I did know about that solution but was trying to avoid it because it takes a lot more operations. But fair enough, it is very robust, this is true.
        – Astrid
        1 hour ago












      up vote
      3
      down vote



      accepted







      up vote
      3
      down vote



      accepted






      The problem is simply rounding errors. The operation int when applied to a (positive?) float, rounds the number down to the nearest integer. This works fine if we pretend that the output of math.log is exact, but it is not:



      >>> math.log(1000, 10)
      2.9999999999999996
      >>> int(math.log(1000, 10))
      2


      There are ways to fix this, e.g. by testing what happens if you compute 10 to the power of the output of this computation, but the more general difficulty is that you can never guarantee that floating point operations will be exact, simply because it's impossible to represent all possible real numbers on a computer.



      In fact, the Pythonic way to solve your problem is the entirely robust function (at least for positive integers, and assuming n takes on a reasonable value)



      def first_n_digits(num, n):
      return int(str(num)[:n])





      share|cite|improve this answer












      The problem is simply rounding errors. The operation int when applied to a (positive?) float, rounds the number down to the nearest integer. This works fine if we pretend that the output of math.log is exact, but it is not:



      >>> math.log(1000, 10)
      2.9999999999999996
      >>> int(math.log(1000, 10))
      2


      There are ways to fix this, e.g. by testing what happens if you compute 10 to the power of the output of this computation, but the more general difficulty is that you can never guarantee that floating point operations will be exact, simply because it's impossible to represent all possible real numbers on a computer.



      In fact, the Pythonic way to solve your problem is the entirely robust function (at least for positive integers, and assuming n takes on a reasonable value)



      def first_n_digits(num, n):
      return int(str(num)[:n])






      share|cite|improve this answer












      share|cite|improve this answer



      share|cite|improve this answer










      answered 1 hour ago









      Mees de Vries

      15.2k12451




      15.2k12451











      • Thanks for that explanation, very helpful. I did know about that solution but was trying to avoid it because it takes a lot more operations. But fair enough, it is very robust, this is true.
        – Astrid
        1 hour ago
















      • Thanks for that explanation, very helpful. I did know about that solution but was trying to avoid it because it takes a lot more operations. But fair enough, it is very robust, this is true.
        – Astrid
        1 hour ago















      Thanks for that explanation, very helpful. I did know about that solution but was trying to avoid it because it takes a lot more operations. But fair enough, it is very robust, this is true.
      – Astrid
      1 hour ago




      Thanks for that explanation, very helpful. I did know about that solution but was trying to avoid it because it takes a lot more operations. But fair enough, it is very robust, this is true.
      – Astrid
      1 hour ago










      up vote
      2
      down vote













      Python documentation for math.log says




      With two arguments, return the logarithm of x to the given base, calculated as log(x)/log(base).




      So it is possible that $textmath.log(1000,10)$ is returning a value very slightly less than 3 due to rounding errors, and when you apply int to this you get $2$. Try evaluating $textint(textmath.log(1000,10))$ to see whether this evaluates to $2$ or $3$. (I see Mees de Vries has already done this test).



      There is an alternative function in the math module called math.log10:




      Return the base-10 logarithm of x. This is usually more accurate than log(x, 10).







      share|cite|improve this answer
























        up vote
        2
        down vote













        Python documentation for math.log says




        With two arguments, return the logarithm of x to the given base, calculated as log(x)/log(base).




        So it is possible that $textmath.log(1000,10)$ is returning a value very slightly less than 3 due to rounding errors, and when you apply int to this you get $2$. Try evaluating $textint(textmath.log(1000,10))$ to see whether this evaluates to $2$ or $3$. (I see Mees de Vries has already done this test).



        There is an alternative function in the math module called math.log10:




        Return the base-10 logarithm of x. This is usually more accurate than log(x, 10).







        share|cite|improve this answer






















          up vote
          2
          down vote










          up vote
          2
          down vote









          Python documentation for math.log says




          With two arguments, return the logarithm of x to the given base, calculated as log(x)/log(base).




          So it is possible that $textmath.log(1000,10)$ is returning a value very slightly less than 3 due to rounding errors, and when you apply int to this you get $2$. Try evaluating $textint(textmath.log(1000,10))$ to see whether this evaluates to $2$ or $3$. (I see Mees de Vries has already done this test).



          There is an alternative function in the math module called math.log10:




          Return the base-10 logarithm of x. This is usually more accurate than log(x, 10).







          share|cite|improve this answer












          Python documentation for math.log says




          With two arguments, return the logarithm of x to the given base, calculated as log(x)/log(base).




          So it is possible that $textmath.log(1000,10)$ is returning a value very slightly less than 3 due to rounding errors, and when you apply int to this you get $2$. Try evaluating $textint(textmath.log(1000,10))$ to see whether this evaluates to $2$ or $3$. (I see Mees de Vries has already done this test).



          There is an alternative function in the math module called math.log10:




          Return the base-10 logarithm of x. This is usually more accurate than log(x, 10).








          share|cite|improve this answer












          share|cite|improve this answer



          share|cite|improve this answer










          answered 1 hour ago









          gandalf61

          6,534522




          6,534522




















              up vote
              -2
              down vote













              The problem is the numerical inaccuracy of Python. Basically when you calculate the logarithm, Python will return 2.999999999... and the int() function will round down to 2. You can use the round()-function instead, e.g. change int(math.log(num, 10)) to round(math.log(num, 10), 1). The second argument tells it to round to integers.



              Alternatively, in Python you can simply transform your integers to strings and back:



              def first_n_digits(num, n):
              return int(str(num)[:n])





              share|cite|improve this answer








              New contributor




              Gemeis is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
              Check out our Code of Conduct.





















                up vote
                -2
                down vote













                The problem is the numerical inaccuracy of Python. Basically when you calculate the logarithm, Python will return 2.999999999... and the int() function will round down to 2. You can use the round()-function instead, e.g. change int(math.log(num, 10)) to round(math.log(num, 10), 1). The second argument tells it to round to integers.



                Alternatively, in Python you can simply transform your integers to strings and back:



                def first_n_digits(num, n):
                return int(str(num)[:n])





                share|cite|improve this answer








                New contributor




                Gemeis is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.



















                  up vote
                  -2
                  down vote










                  up vote
                  -2
                  down vote









                  The problem is the numerical inaccuracy of Python. Basically when you calculate the logarithm, Python will return 2.999999999... and the int() function will round down to 2. You can use the round()-function instead, e.g. change int(math.log(num, 10)) to round(math.log(num, 10), 1). The second argument tells it to round to integers.



                  Alternatively, in Python you can simply transform your integers to strings and back:



                  def first_n_digits(num, n):
                  return int(str(num)[:n])





                  share|cite|improve this answer








                  New contributor




                  Gemeis is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.









                  The problem is the numerical inaccuracy of Python. Basically when you calculate the logarithm, Python will return 2.999999999... and the int() function will round down to 2. You can use the round()-function instead, e.g. change int(math.log(num, 10)) to round(math.log(num, 10), 1). The second argument tells it to round to integers.



                  Alternatively, in Python you can simply transform your integers to strings and back:



                  def first_n_digits(num, n):
                  return int(str(num)[:n])






                  share|cite|improve this answer








                  New contributor




                  Gemeis is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.









                  share|cite|improve this answer



                  share|cite|improve this answer






                  New contributor




                  Gemeis is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.









                  answered 1 hour ago









                  Gemeis

                  1




                  1




                  New contributor




                  Gemeis is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.





                  New contributor





                  Gemeis is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.






                  Gemeis is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.



























                       

                      draft saved


                      draft discarded















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmath.stackexchange.com%2fquestions%2f2952462%2ffinding-the-leading-digits-in-any-number%23new-answer', 'question_page');

                      );

                      Post as a guest













































































                      Comments

                      Popular posts from this blog

                      What does second last employer means? [closed]

                      List of Gilmore Girls characters

                      Confectionery