Join the discussion

Write your take first — we'll ask for email only when you're ready to publish.

  • Hacker News
  • > Why include a script rather than a proof? One reason is that the proof is straight-forward but tedious and the script is compact.

    Yes the script lets you check that the result is correct, but a proof lets you see why it's correct. A good proof might even give you a sense of how you could have discovered the result yourself, or how you might generalize it.

  • Feels like a Temu version of Ramanujan's constant [0].

    [0] https://mathworld.wolfram.com/RamanujanConstant.html

  • Why the b > 2 condition? In the b=2 case, all three formulas also work perfectly, providing a ratio of 1. And this is interesting case where the error term is integer and the only case where that error term (1) is dominant (b-2=0), while the b-2 part dominates for larger bases.
  • in the b=2 case, you get:

      1 / 1 = 1 = b - 1
      1 % 1 = 0 = b - 2
    
    they are the other way around, see for example the b=3 case:

      21 (base 3) = 7
      12 (base 3) = 5
      7 / 5 = 1 = b - 2
      7 % 5 = 2 = b - 1
  • See perhaps various "What every programmer / CSist should know about floating-point arithmetic" papers and articles:

    * David Goldberg, 1991: https://dl.acm.org/doi/10.1145/103162.103163

    * 2014, "Floating Point Demystified, Part 1": https://blog.reverberate.org/2014/09/what-every-computer-pro... ; https://news.ycombinator.com/item?id=8321940

    * 2015: https://www.phys.uconn.edu/~rozman/Courses/P2200_15F/downloa...

  • As someone who has recently been fighting bugs from representing very simple math with floats... thank you!
  • Here is a correction which m akes it exactly 8.0:

      > 987654320 / 123456790
      8.0
    
    I've decremented the numerator and incremented the denominator:

       ( 987654321 - 1 )
       -----------------  = 8
       ( 123456789 + 1 )
    
    Works in other bases. TXR Lisp, base 4:

      1> (/ (poly 4 '(3 2 1)) (poly 4 '(1 2 3)))
      2.11111111111111
      2> (/ (poly 4 '(3 2 0)) (poly 4 '(1 2 4)))
      2.0
    
    It also works for base 2, which is below the lowest base used in the article: the Python code goes from 3.

    For base 2, the ratio is 1/1. When we apply the correction, we get (1 - 1) / (1 + 1) = 0, which is 2 - 2.

  • This is fun! but not so surprising to me:

    987,654,321 + 123,456,789 = 1,111,111,110

    1,111,111,110 + 123,456,789 = 1,234,567,899 \approx 1,234,567,890

    So 987,654,321 + 2 x 123,456,789 \approx 10 x 123,456,789

    Thus 987,654,321 / 123,456,789 \approx 8.

    If you squint you can see how it would work similarly in other bases. Add the 123... equivalent once to get the base-independent series of 1's, add a second time to get the base-independent 123...0.

  • I like to think of 0.987654... and 0.123456... as infinite series which simplify to 80/81 and 10/81, hence the ~8 ratio.
  • Care to elaborate? Why does 0.987654 simplify to 80/81 and 0.123456 to 10/81?
  • I didn't get where this comes from until I saw the second answer from the StackOverflow question another commenter shared.

    https://math.stackexchange.com/a/2268896

    Apparently 1/9^2 is well known to be 0.12345679(012345679)...

    EDIT: Yes it's missing the 8 (I wrote it wrong intially): https://math.stackexchange.com/questions/994203/why-do-we-mi...

    Interesting how it works out but I don't think it is anywhere close to as intuitive as the parent comment implies. The way its phrased made me feel a bit dumb because I didn't get it right away, but in retrospect I don't think anyone would reasonably get it without context.

  • I like calculator quirks like this. I remember as a kid playing with the number pad and noticing a geometric center of mass in number sequences

        ┌───┬───┬───┐
        │ 7 │ 8 │ 9 │
        ├───┼───┼───┤
        │ 4 │ 5 │ 6 │
        ├───┼───┼───┤
        │ 1 │ 2 │ 3 │
        ├───┼───┼───┤
        │ 0 │ . │   │
        └───┴───┴───┘
    
    I remember seeing that (14787 + 36989) / 2 would produce 25888, in that the mean of geometric shape traced by the two sequences would average out in the middle like that
  • how did you submit this table in HN??
    by a13n
  • now there's some solid ascii, great work sir
  • Great, now I'm getting Carrot Top flashbacks. "Dial right down the center of the phone!"

    For non-Americans and/or those too young to remember when landline service was still dominant, in the 90s and early 2000s AT&T ran a collect-call service accessible through the number 1-800-CALL-ATT (1-800-225-5288) and promoted it with ads featuring comedian Carrot Top. And if you don't know who Carrot Top is, maybe that's for the best.

  • 14789 + 36987 / 2 would do the same thing. Why trace back?
  • i remember the 1110 thing on a calc as well.

    741 + 369 & 963 + 147 | 123 + 987 & 321 + 789 (left right | up down)

    159 + 951 & 753 + 357 | 258 + 852 & 456 + 654 (diagonally | center lines)

    the design of a keypad... it unintentionally contains these elegant mathematical relationships.

    i call this phenomena: outcomes of human creations can be "funny and odd", and everybody understand that eventually there will be always something unpredictable.

  • The even simpler example is more striking imo.

    (147 + 369) / 2 = 258

    and

    (741 + 963) / 2 = 852

  • Let's prove it.

    In general, sum(x^k, k=1…n) = x(1-x^n)/(1-x).

    Then sum(kx^(k-1), k=1…n) = d/dx sum(x^k, k=1…n) = d/dx (x(1-x^n))/(1-x) = (nx^(n+1) - (n+1)x^n + 1)/(1-x)^2

    With x=b, n=b-1, the numerator as defined in TFA is n = sum(kb^(k-1), k=1…b-1) = ((b-2)b^b + 1)/(1-b)^2 = ((b-2)b^b + 1)/(1-b)^2.

    And the denominator is:

    d = sum((b-k)b^(k-1), k=1..b-1) = sum(b^k, k=1..b-1) - sum(kb^(k-1), k=1..b-1) = (b-b^b)/(1-b) - n = (b^b - b^2 + b - 1)/(1-b)^2.

    Then, n-(b-1) = (b^(b+1) - 2b^b - b^3 + 3b^2 - 3b +2)/(1-b)^2.

    And d(b-2) = the same thing.

    So n = d(b-2) + b - 1, whence n/d = b-2 + (b-1)/d.

    We also see that the dominant term in d will be b^b/(1-b)^2 which grows like b^(b-2), which is why the fractional part of n/d is 1 over that.

    I disagree with the author that a script works as well as a proof. Scripts are neither constructive nor exhaustive.

  • If you want to be lazier, after finding the generating functions one can plug into sympy to skip the algebra.
  • The author does not say a script works as well as a proof.
  • The other replies are good, but let's add another one anyway.

    0.987654321/0.123456789 = (1.11111111-x)/x = 1.11111111/x - 1 where x = 0.123456789

    You can aproxímate 1.11111111 by 10/9 and aproxímate x = 0.123456789 using y = 0.123456789ABCD... = 0.123456789(10)(11)(12)(13)... that is a number in base 10 that is not written correctly and has digits that are greater than 9. I.E. y = sum_i>0 i/10^i

    Now you can consider the function f(t) = t + 2 t^2 + 3 t^3 + 4 t^4 + ... = sum_i>0 i*t^i and y is just y=f(0.1).

    And also consider an auxiliary function g(t) = t + t^2 + t^3 + t^4 + ... = sum_i>0 1*t^i . A nice property is that g(t)= 1/(1-t) when -1<t<1.

    The problem with g is that it lacks the coefficients, but that can be solved taking the derivative. g'(t) = 1 + 2 t + 3 t^2 + 4 t^3 + ... Now the coefficients are shifted but it can be solved multiplying by t. So f(t)=t*g'(t).

    So f(t) = t * (1/(1-t))' = t * (1/(1-t)^2) = t/(1-t)^2

    and y = f(0.1) = .1/.9^2 = 10/81

    then 0.987654321/0.123456789 ~= (10/9-y)/y = 10/(9y)-1 = 9 - 1 = 8

    Now add some error bounds using the Taylor method to get the difference between x and y, and also a bound for the difference between 1.11111111 an 10/9. It shoud take like 15 minutes to get all the details right, but I'm too lazy.

    (As I said in another comment, all these series have a good convergence for |z|<1, so by standards methods of complex analysis all the series tricks are correct.)

  • An easier way to evaluate sum i/10^i is by squaring sum 1/10^i

    If you multiply term by term every term has coefficient 1 of course. There are n terms with exponent n+1, made from the n sums of the first exponent and the second exponent.

    Eg 1+5, 2+4, 3+3, 4+2, 5+1.

    So (1/9)^2 = (sum 1/10^i)^2 = 1/10 sum i/10^i

    The derivative trick is more useful generally, but this method gets you the solution to 0.12345678.. in an quick way that's also easier to justify that it works.

  • This was by far the most interesting part to me. I've never considered that code and proofs can be so complementary. It would be great if someone did this for all math proofs!

    "Why include a script rather than a proof? One reason is that the proof is straight-forward but tedious and the script is compact.

    A more general reason that I give computational demonstrations of theorems is that programs are complementary to proofs. Programs and proofs are both subject to bugs, but they’re not likely to have the same bugs. And because programs made details explicit by necessity, a program might fill in gaps that aren’t sufficiently spelled out in a proof."

  • I came here to quote that entire section as well I’m glad I checked the comments first.

    I’ve never seen a more succinct explanation of the value of coding up scripts to demonstrate proofs.

    I think I’ll tighten it up to “proofs have bugs” in the future.

  • This is misleading in that the (Curry–Howard) correspondence is between proofs and the static typing of programs. A bug in a proof therefore corresponds to a bug in the static typing of a program (or to the type system of the programming language being unsound), not to any other program bug.

    (Also: complementary != complimentary.)

  • As a kid, I was marginally decent at competitive math. Not good like you think of kids who dominate those type of competitions at a high level, but like I could qualify for the state competition type good.

    What I was actually good, or at least fast at, was TI-Basic, which was allowed in a lot of cases (though not all). Usually the problems were set up so you couldn’t find the solution using just the calculator, but if you had a couple of ideas and needed to choose between them you could sometimes cross off the wrong ones with a program.

    The script the author gives isn’t a proof itself, unless the proposition is false, in which case a counter example always makes a great proof :p

  • Somewhat interesting, 123456789 * 8 is 987654312 (the last two digits are swapped). This holds for other bases as well: 0x123456789ABCDEF * 14 is 0xFEDCBA987654312.

    Also, adding 123456789 to itself eight times on an abacus is a nice exercise, and it's easy to visually control the end result.

  • On an 8 digit calculator the common variant of this was

        12345679 * 8 = 98765432
  • > the last 2 digits are swapped

    They are also +9 away from being in order.

    And then 12345678 * 8 is 98765424 which is +9 away from also being in order.