Is integer division always equal to the floor of regular division?












22














For large quotients, integer division (//) doesn't seem to be necessarily equal to the floor of regular division (math.floor(a/b)).



According to Python docs (https://docs.python.org/3/reference/expressions.html - 6.7),




floor division of integers results in an integer; the result is that of mathematical division with the ‘floor’ function applied to the result.




However,



math.floor(648705536316023400 / 7) = 92672219473717632

648705536316023400 // 7 = 92672219473717628


'{0:.10f}'.format(648705536316023400 / 7) yields '92672219473717632.0000000000', but the last two digits of the decimal part should be 28 and not 32.










share|improve this question









New contributor




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
















  • 1




    In case it's not clear from the answers below -- the issue is that when the docs define "floor division" (//) in terms of "mathematical division", the term "mathematical division" does not refer to Python "division" /. Rather, "division" / and "floor division" // are two different approximations to true ("mathematical") division.
    – ruakh
    Dec 22 at 6:07
















22














For large quotients, integer division (//) doesn't seem to be necessarily equal to the floor of regular division (math.floor(a/b)).



According to Python docs (https://docs.python.org/3/reference/expressions.html - 6.7),




floor division of integers results in an integer; the result is that of mathematical division with the ‘floor’ function applied to the result.




However,



math.floor(648705536316023400 / 7) = 92672219473717632

648705536316023400 // 7 = 92672219473717628


'{0:.10f}'.format(648705536316023400 / 7) yields '92672219473717632.0000000000', but the last two digits of the decimal part should be 28 and not 32.










share|improve this question









New contributor




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
















  • 1




    In case it's not clear from the answers below -- the issue is that when the docs define "floor division" (//) in terms of "mathematical division", the term "mathematical division" does not refer to Python "division" /. Rather, "division" / and "floor division" // are two different approximations to true ("mathematical") division.
    – ruakh
    Dec 22 at 6:07














22












22








22


2





For large quotients, integer division (//) doesn't seem to be necessarily equal to the floor of regular division (math.floor(a/b)).



According to Python docs (https://docs.python.org/3/reference/expressions.html - 6.7),




floor division of integers results in an integer; the result is that of mathematical division with the ‘floor’ function applied to the result.




However,



math.floor(648705536316023400 / 7) = 92672219473717632

648705536316023400 // 7 = 92672219473717628


'{0:.10f}'.format(648705536316023400 / 7) yields '92672219473717632.0000000000', but the last two digits of the decimal part should be 28 and not 32.










share|improve this question









New contributor




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











For large quotients, integer division (//) doesn't seem to be necessarily equal to the floor of regular division (math.floor(a/b)).



According to Python docs (https://docs.python.org/3/reference/expressions.html - 6.7),




floor division of integers results in an integer; the result is that of mathematical division with the ‘floor’ function applied to the result.




However,



math.floor(648705536316023400 / 7) = 92672219473717632

648705536316023400 // 7 = 92672219473717628


'{0:.10f}'.format(648705536316023400 / 7) yields '92672219473717632.0000000000', but the last two digits of the decimal part should be 28 and not 32.







python integer division floating-accuracy integer-division






share|improve this question









New contributor




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











share|improve this question









New contributor




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









share|improve this question




share|improve this question








edited Dec 21 at 22:58









dan04

62.3k15134173




62.3k15134173






New contributor




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









asked Dec 21 at 22:44









Aditya Chanana

1113




1113




New contributor




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





New contributor





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






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








  • 1




    In case it's not clear from the answers below -- the issue is that when the docs define "floor division" (//) in terms of "mathematical division", the term "mathematical division" does not refer to Python "division" /. Rather, "division" / and "floor division" // are two different approximations to true ("mathematical") division.
    – ruakh
    Dec 22 at 6:07














  • 1




    In case it's not clear from the answers below -- the issue is that when the docs define "floor division" (//) in terms of "mathematical division", the term "mathematical division" does not refer to Python "division" /. Rather, "division" / and "floor division" // are two different approximations to true ("mathematical") division.
    – ruakh
    Dec 22 at 6:07








1




1




In case it's not clear from the answers below -- the issue is that when the docs define "floor division" (//) in terms of "mathematical division", the term "mathematical division" does not refer to Python "division" /. Rather, "division" / and "floor division" // are two different approximations to true ("mathematical") division.
– ruakh
Dec 22 at 6:07




In case it's not clear from the answers below -- the issue is that when the docs define "floor division" (//) in terms of "mathematical division", the term "mathematical division" does not refer to Python "division" /. Rather, "division" / and "floor division" // are two different approximations to true ("mathematical") division.
– ruakh
Dec 22 at 6:07












3 Answers
3






active

oldest

votes


















26














The reason the quotients in your test case are not equal is that in the math.floor(a/b) case, the result is calculated with floating point arithmetic (IEEE-754 64-bit), which means there is a maximum precision. The quotient you have there is larger than the 253 limit above which floating point is no longer accurate up to the unit.



With the integer division however, Python uses its unlimited integer range, and so that result is correct.



See also "Semantics of True Division" in PEP 238:




Note that for int and long arguments, true division may lose information; this is in the nature of true division (as long as rationals are not in the language). Algorithms that consciously use longs should consider using //, as true division of longs retains no more than 53 bits of precision (on most platforms).







share|improve this answer























  • TIL that Python calls floating-point division "true division." Floating-point division is inexact by definition, whereas integer division is exact by definition; it's super weird that Python deliberately chose the name "true division" for the inexact version. Huh.
    – Quuxplusone
    Dec 22 at 16:13



















16














You may be dealing with integral values that are too large to express exactly as floats. Your number is significantly larger than 2^53, which is where the gaps between adjacent floating point doubles start to get bigger than 1. So you lose some precision when doing the floating point division.



The integer division, on the other hand, is computed exactly.






share|improve this answer





























    4














    Your problem is that, despite the fact that "/" is sometimes called the "true division operator" and its method name is __truediv__, its behavior on integers is not "true mathematical division". Instead it produces a floating point result which inevitably has limited precision.



    For sufficiently large numbers even the integral part of a number can suffer from floating point rounding errors. When 648705536316023400 is converted to a Python float (IEEE double) it gets rounded to 6487055363160234241.



    I can't seem to find authoritative documentation on the exact behavior of the operators on the built-in types in current Python. The original PEP that introduced the feature states that "/" is equivalent to converting the integers to floating point and then performing floating point division. However a quick test in Python 3.5 shows that not to be the case. If it was then the following code would produce no output.



    for i in range(648705536316023400,648705536316123400):
    if math.floor(i/7) != math.floor(float(i)/7):
    print(i)


    But at least for me it does produce output.



    Instead it seems to me that Python is performing the division on the numbers as presented and rounding the result to fit in a floating point number. Taking an example from that programs output.



    648705536316123383 // 7                   == 92672219473731911
    math.floor(648705536316123383 / 7) == 92672219473731904
    math.floor(float(648705536316123383) / 7) == 92672219473731920
    int(float(92672219473731911)) == 92672219473731904


    The Python standard library does provide a Fraction type and the division operator for a Fraction divided by an int does perform "true mathematical division".



    math.floor(Fraction(648705536316023400) / 7) == 92672219473717628
    math.floor(Fraction(648705536316123383) / 7) == 92672219473731911


    However you should be aware of the potentially severe performance and memory implications of using the Fraction type. Remember fractions can increase in storage requirement without increasing in magnitude.





    To further test my theory of "one rounding vs two" I did a test with the following code.



    #!/usr/bin/python3
    from fractions import Fraction
    edt = 0
    eft = 0
    base = 1000000000010000000000
    top = base + 1000000
    for i in range(base,top):
    ex = (Fraction(i)/7)
    di = (i/7)
    fl = (float(i)/7)
    ed = abs(ex-Fraction(di))
    ef = abs(ex-Fraction(fl))
    edt += ed
    eft += ef
    print(edt/10000000000)
    print(eft/10000000000)


    And the average error magnitude was substantially smaller for performing the division directly than for converting to float first, supporting the one rounding vs two theory.



    1Note that printing a float directly does not show its exact value, instead it shows the shortest decimal number that will round to that value (allowing lossless round-trip conversion from float to string and back to float).






    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      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',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });






      Aditya Chanana is a new contributor. Be nice, and check out our Code of Conduct.










      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53891566%2fis-integer-division-always-equal-to-the-floor-of-regular-division%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      26














      The reason the quotients in your test case are not equal is that in the math.floor(a/b) case, the result is calculated with floating point arithmetic (IEEE-754 64-bit), which means there is a maximum precision. The quotient you have there is larger than the 253 limit above which floating point is no longer accurate up to the unit.



      With the integer division however, Python uses its unlimited integer range, and so that result is correct.



      See also "Semantics of True Division" in PEP 238:




      Note that for int and long arguments, true division may lose information; this is in the nature of true division (as long as rationals are not in the language). Algorithms that consciously use longs should consider using //, as true division of longs retains no more than 53 bits of precision (on most platforms).







      share|improve this answer























      • TIL that Python calls floating-point division "true division." Floating-point division is inexact by definition, whereas integer division is exact by definition; it's super weird that Python deliberately chose the name "true division" for the inexact version. Huh.
        – Quuxplusone
        Dec 22 at 16:13
















      26














      The reason the quotients in your test case are not equal is that in the math.floor(a/b) case, the result is calculated with floating point arithmetic (IEEE-754 64-bit), which means there is a maximum precision. The quotient you have there is larger than the 253 limit above which floating point is no longer accurate up to the unit.



      With the integer division however, Python uses its unlimited integer range, and so that result is correct.



      See also "Semantics of True Division" in PEP 238:




      Note that for int and long arguments, true division may lose information; this is in the nature of true division (as long as rationals are not in the language). Algorithms that consciously use longs should consider using //, as true division of longs retains no more than 53 bits of precision (on most platforms).







      share|improve this answer























      • TIL that Python calls floating-point division "true division." Floating-point division is inexact by definition, whereas integer division is exact by definition; it's super weird that Python deliberately chose the name "true division" for the inexact version. Huh.
        – Quuxplusone
        Dec 22 at 16:13














      26












      26








      26






      The reason the quotients in your test case are not equal is that in the math.floor(a/b) case, the result is calculated with floating point arithmetic (IEEE-754 64-bit), which means there is a maximum precision. The quotient you have there is larger than the 253 limit above which floating point is no longer accurate up to the unit.



      With the integer division however, Python uses its unlimited integer range, and so that result is correct.



      See also "Semantics of True Division" in PEP 238:




      Note that for int and long arguments, true division may lose information; this is in the nature of true division (as long as rationals are not in the language). Algorithms that consciously use longs should consider using //, as true division of longs retains no more than 53 bits of precision (on most platforms).







      share|improve this answer














      The reason the quotients in your test case are not equal is that in the math.floor(a/b) case, the result is calculated with floating point arithmetic (IEEE-754 64-bit), which means there is a maximum precision. The quotient you have there is larger than the 253 limit above which floating point is no longer accurate up to the unit.



      With the integer division however, Python uses its unlimited integer range, and so that result is correct.



      See also "Semantics of True Division" in PEP 238:




      Note that for int and long arguments, true division may lose information; this is in the nature of true division (as long as rationals are not in the language). Algorithms that consciously use longs should consider using //, as true division of longs retains no more than 53 bits of precision (on most platforms).








      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Dec 22 at 8:47

























      answered Dec 21 at 22:51









      trincot

      117k1480110




      117k1480110












      • TIL that Python calls floating-point division "true division." Floating-point division is inexact by definition, whereas integer division is exact by definition; it's super weird that Python deliberately chose the name "true division" for the inexact version. Huh.
        – Quuxplusone
        Dec 22 at 16:13


















      • TIL that Python calls floating-point division "true division." Floating-point division is inexact by definition, whereas integer division is exact by definition; it's super weird that Python deliberately chose the name "true division" for the inexact version. Huh.
        – Quuxplusone
        Dec 22 at 16:13
















      TIL that Python calls floating-point division "true division." Floating-point division is inexact by definition, whereas integer division is exact by definition; it's super weird that Python deliberately chose the name "true division" for the inexact version. Huh.
      – Quuxplusone
      Dec 22 at 16:13




      TIL that Python calls floating-point division "true division." Floating-point division is inexact by definition, whereas integer division is exact by definition; it's super weird that Python deliberately chose the name "true division" for the inexact version. Huh.
      – Quuxplusone
      Dec 22 at 16:13













      16














      You may be dealing with integral values that are too large to express exactly as floats. Your number is significantly larger than 2^53, which is where the gaps between adjacent floating point doubles start to get bigger than 1. So you lose some precision when doing the floating point division.



      The integer division, on the other hand, is computed exactly.






      share|improve this answer


























        16














        You may be dealing with integral values that are too large to express exactly as floats. Your number is significantly larger than 2^53, which is where the gaps between adjacent floating point doubles start to get bigger than 1. So you lose some precision when doing the floating point division.



        The integer division, on the other hand, is computed exactly.






        share|improve this answer
























          16












          16








          16






          You may be dealing with integral values that are too large to express exactly as floats. Your number is significantly larger than 2^53, which is where the gaps between adjacent floating point doubles start to get bigger than 1. So you lose some precision when doing the floating point division.



          The integer division, on the other hand, is computed exactly.






          share|improve this answer












          You may be dealing with integral values that are too large to express exactly as floats. Your number is significantly larger than 2^53, which is where the gaps between adjacent floating point doubles start to get bigger than 1. So you lose some precision when doing the floating point division.



          The integer division, on the other hand, is computed exactly.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Dec 21 at 22:53









          interfect

          1,4611021




          1,4611021























              4














              Your problem is that, despite the fact that "/" is sometimes called the "true division operator" and its method name is __truediv__, its behavior on integers is not "true mathematical division". Instead it produces a floating point result which inevitably has limited precision.



              For sufficiently large numbers even the integral part of a number can suffer from floating point rounding errors. When 648705536316023400 is converted to a Python float (IEEE double) it gets rounded to 6487055363160234241.



              I can't seem to find authoritative documentation on the exact behavior of the operators on the built-in types in current Python. The original PEP that introduced the feature states that "/" is equivalent to converting the integers to floating point and then performing floating point division. However a quick test in Python 3.5 shows that not to be the case. If it was then the following code would produce no output.



              for i in range(648705536316023400,648705536316123400):
              if math.floor(i/7) != math.floor(float(i)/7):
              print(i)


              But at least for me it does produce output.



              Instead it seems to me that Python is performing the division on the numbers as presented and rounding the result to fit in a floating point number. Taking an example from that programs output.



              648705536316123383 // 7                   == 92672219473731911
              math.floor(648705536316123383 / 7) == 92672219473731904
              math.floor(float(648705536316123383) / 7) == 92672219473731920
              int(float(92672219473731911)) == 92672219473731904


              The Python standard library does provide a Fraction type and the division operator for a Fraction divided by an int does perform "true mathematical division".



              math.floor(Fraction(648705536316023400) / 7) == 92672219473717628
              math.floor(Fraction(648705536316123383) / 7) == 92672219473731911


              However you should be aware of the potentially severe performance and memory implications of using the Fraction type. Remember fractions can increase in storage requirement without increasing in magnitude.





              To further test my theory of "one rounding vs two" I did a test with the following code.



              #!/usr/bin/python3
              from fractions import Fraction
              edt = 0
              eft = 0
              base = 1000000000010000000000
              top = base + 1000000
              for i in range(base,top):
              ex = (Fraction(i)/7)
              di = (i/7)
              fl = (float(i)/7)
              ed = abs(ex-Fraction(di))
              ef = abs(ex-Fraction(fl))
              edt += ed
              eft += ef
              print(edt/10000000000)
              print(eft/10000000000)


              And the average error magnitude was substantially smaller for performing the division directly than for converting to float first, supporting the one rounding vs two theory.



              1Note that printing a float directly does not show its exact value, instead it shows the shortest decimal number that will round to that value (allowing lossless round-trip conversion from float to string and back to float).






              share|improve this answer




























                4














                Your problem is that, despite the fact that "/" is sometimes called the "true division operator" and its method name is __truediv__, its behavior on integers is not "true mathematical division". Instead it produces a floating point result which inevitably has limited precision.



                For sufficiently large numbers even the integral part of a number can suffer from floating point rounding errors. When 648705536316023400 is converted to a Python float (IEEE double) it gets rounded to 6487055363160234241.



                I can't seem to find authoritative documentation on the exact behavior of the operators on the built-in types in current Python. The original PEP that introduced the feature states that "/" is equivalent to converting the integers to floating point and then performing floating point division. However a quick test in Python 3.5 shows that not to be the case. If it was then the following code would produce no output.



                for i in range(648705536316023400,648705536316123400):
                if math.floor(i/7) != math.floor(float(i)/7):
                print(i)


                But at least for me it does produce output.



                Instead it seems to me that Python is performing the division on the numbers as presented and rounding the result to fit in a floating point number. Taking an example from that programs output.



                648705536316123383 // 7                   == 92672219473731911
                math.floor(648705536316123383 / 7) == 92672219473731904
                math.floor(float(648705536316123383) / 7) == 92672219473731920
                int(float(92672219473731911)) == 92672219473731904


                The Python standard library does provide a Fraction type and the division operator for a Fraction divided by an int does perform "true mathematical division".



                math.floor(Fraction(648705536316023400) / 7) == 92672219473717628
                math.floor(Fraction(648705536316123383) / 7) == 92672219473731911


                However you should be aware of the potentially severe performance and memory implications of using the Fraction type. Remember fractions can increase in storage requirement without increasing in magnitude.





                To further test my theory of "one rounding vs two" I did a test with the following code.



                #!/usr/bin/python3
                from fractions import Fraction
                edt = 0
                eft = 0
                base = 1000000000010000000000
                top = base + 1000000
                for i in range(base,top):
                ex = (Fraction(i)/7)
                di = (i/7)
                fl = (float(i)/7)
                ed = abs(ex-Fraction(di))
                ef = abs(ex-Fraction(fl))
                edt += ed
                eft += ef
                print(edt/10000000000)
                print(eft/10000000000)


                And the average error magnitude was substantially smaller for performing the division directly than for converting to float first, supporting the one rounding vs two theory.



                1Note that printing a float directly does not show its exact value, instead it shows the shortest decimal number that will round to that value (allowing lossless round-trip conversion from float to string and back to float).






                share|improve this answer


























                  4












                  4








                  4






                  Your problem is that, despite the fact that "/" is sometimes called the "true division operator" and its method name is __truediv__, its behavior on integers is not "true mathematical division". Instead it produces a floating point result which inevitably has limited precision.



                  For sufficiently large numbers even the integral part of a number can suffer from floating point rounding errors. When 648705536316023400 is converted to a Python float (IEEE double) it gets rounded to 6487055363160234241.



                  I can't seem to find authoritative documentation on the exact behavior of the operators on the built-in types in current Python. The original PEP that introduced the feature states that "/" is equivalent to converting the integers to floating point and then performing floating point division. However a quick test in Python 3.5 shows that not to be the case. If it was then the following code would produce no output.



                  for i in range(648705536316023400,648705536316123400):
                  if math.floor(i/7) != math.floor(float(i)/7):
                  print(i)


                  But at least for me it does produce output.



                  Instead it seems to me that Python is performing the division on the numbers as presented and rounding the result to fit in a floating point number. Taking an example from that programs output.



                  648705536316123383 // 7                   == 92672219473731911
                  math.floor(648705536316123383 / 7) == 92672219473731904
                  math.floor(float(648705536316123383) / 7) == 92672219473731920
                  int(float(92672219473731911)) == 92672219473731904


                  The Python standard library does provide a Fraction type and the division operator for a Fraction divided by an int does perform "true mathematical division".



                  math.floor(Fraction(648705536316023400) / 7) == 92672219473717628
                  math.floor(Fraction(648705536316123383) / 7) == 92672219473731911


                  However you should be aware of the potentially severe performance and memory implications of using the Fraction type. Remember fractions can increase in storage requirement without increasing in magnitude.





                  To further test my theory of "one rounding vs two" I did a test with the following code.



                  #!/usr/bin/python3
                  from fractions import Fraction
                  edt = 0
                  eft = 0
                  base = 1000000000010000000000
                  top = base + 1000000
                  for i in range(base,top):
                  ex = (Fraction(i)/7)
                  di = (i/7)
                  fl = (float(i)/7)
                  ed = abs(ex-Fraction(di))
                  ef = abs(ex-Fraction(fl))
                  edt += ed
                  eft += ef
                  print(edt/10000000000)
                  print(eft/10000000000)


                  And the average error magnitude was substantially smaller for performing the division directly than for converting to float first, supporting the one rounding vs two theory.



                  1Note that printing a float directly does not show its exact value, instead it shows the shortest decimal number that will round to that value (allowing lossless round-trip conversion from float to string and back to float).






                  share|improve this answer














                  Your problem is that, despite the fact that "/" is sometimes called the "true division operator" and its method name is __truediv__, its behavior on integers is not "true mathematical division". Instead it produces a floating point result which inevitably has limited precision.



                  For sufficiently large numbers even the integral part of a number can suffer from floating point rounding errors. When 648705536316023400 is converted to a Python float (IEEE double) it gets rounded to 6487055363160234241.



                  I can't seem to find authoritative documentation on the exact behavior of the operators on the built-in types in current Python. The original PEP that introduced the feature states that "/" is equivalent to converting the integers to floating point and then performing floating point division. However a quick test in Python 3.5 shows that not to be the case. If it was then the following code would produce no output.



                  for i in range(648705536316023400,648705536316123400):
                  if math.floor(i/7) != math.floor(float(i)/7):
                  print(i)


                  But at least for me it does produce output.



                  Instead it seems to me that Python is performing the division on the numbers as presented and rounding the result to fit in a floating point number. Taking an example from that programs output.



                  648705536316123383 // 7                   == 92672219473731911
                  math.floor(648705536316123383 / 7) == 92672219473731904
                  math.floor(float(648705536316123383) / 7) == 92672219473731920
                  int(float(92672219473731911)) == 92672219473731904


                  The Python standard library does provide a Fraction type and the division operator for a Fraction divided by an int does perform "true mathematical division".



                  math.floor(Fraction(648705536316023400) / 7) == 92672219473717628
                  math.floor(Fraction(648705536316123383) / 7) == 92672219473731911


                  However you should be aware of the potentially severe performance and memory implications of using the Fraction type. Remember fractions can increase in storage requirement without increasing in magnitude.





                  To further test my theory of "one rounding vs two" I did a test with the following code.



                  #!/usr/bin/python3
                  from fractions import Fraction
                  edt = 0
                  eft = 0
                  base = 1000000000010000000000
                  top = base + 1000000
                  for i in range(base,top):
                  ex = (Fraction(i)/7)
                  di = (i/7)
                  fl = (float(i)/7)
                  ed = abs(ex-Fraction(di))
                  ef = abs(ex-Fraction(fl))
                  edt += ed
                  eft += ef
                  print(edt/10000000000)
                  print(eft/10000000000)


                  And the average error magnitude was substantially smaller for performing the division directly than for converting to float first, supporting the one rounding vs two theory.



                  1Note that printing a float directly does not show its exact value, instead it shows the shortest decimal number that will round to that value (allowing lossless round-trip conversion from float to string and back to float).







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 2 days ago

























                  answered Dec 22 at 7:30









                  plugwash

                  4,2451124




                  4,2451124






















                      Aditya Chanana is a new contributor. Be nice, and check out our Code of Conduct.










                      draft saved

                      draft discarded


















                      Aditya Chanana is a new contributor. Be nice, and check out our Code of Conduct.













                      Aditya Chanana is a new contributor. Be nice, and check out our Code of Conduct.












                      Aditya Chanana is a new contributor. Be nice, and check out our Code of Conduct.
















                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53891566%2fis-integer-division-always-equal-to-the-floor-of-regular-division%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Список кардиналов, возведённых папой римским Каликстом III

                      Deduzione

                      Mysql.sock missing - “Can't connect to local MySQL server through socket”