News for hackers. Stuff that matters.
Re:Fast midpoint between two integers without overflow by webstrand on Wednesday December 07, 2022 @09:19AM (#33894582)
This should be possible for static languages? Since the width of the operands are known ahead of time, a wider integer can be unconditionally reserved on the stack for the result of the operation.

I'm curious which dynamic language reallocates to store larger integers? All of the dynamic languages that I'm familiar with simply store numbers as doubles, with variable width integers being handled by opt-in types.

Re:Fast midpoint between two integers without overflow by Aaargh20318 on Wednesday December 07, 2022 @09:57AM (#33895009)
But if you do this in a static language you’d quickly run out of space anyway.

Say you start with two Int16’s. Any addition would result in an Int17. Adding a pair of those together would result in an Int18, and so forth.

You’d blow past Int64 in no time.

Re:Fast midpoint between two integers without overflow by dekhn on Wednesday December 07, 2022 @10:00AM (#33895046)
I'm pretty sure their intent was to demote the value back to an int16 after completing the midpoint operation.
Re:Fast midpoint between two integers without overflow by IncRnd on Wednesday December 07, 2022 @10:59AM (#33895860)
> You’d blow past Int64 in no time.

Not really. You only need to preserve according to the msb of each number. If you are adding 0(Int18)+1(Int18), you don't need 1(Int36) anymore than you need 1(Int18) or even 1(Int1).

Re:Fast midpoint between two integers without overflow by tsimionescu on Wednesday December 07, 2022 @12:31PM (#33897298)
But you don't know the MSB at compile time in the general case.
Re:Fast midpoint between two integers without overflow by Aaargh20318 on Wednesday December 07, 2022 @03:17PM (#33899658)
> If you are adding 0(Int18)+1(Int18), you don't need 1(Int36)

No, you’d need an Int19. We were talking about statically typed languages, so you need to decide the type at compile-time. If you add two UInt16’s they could both contain up to 0xFFFF, you need 17 bits to store that answer. Basically, with every addition you need 1 more bit than the largest of the two (types, not values) you are adding together to prevent a potential overflow. It’s even worse for multiplication.

Re:Fast midpoint between two integers without overflow by taeric on Wednesday December 07, 2022 @03:43PM (#33899953)
Couldn't you have a constraining operation in there to assert that you have enough bits? You are right that we don't know if `a + b` would need more bits than either a or b. However, we could have an assert that allows us to ensure the static constraints are satisfied. And the type system could be used as a place to know where we haven't checked the constraint.

(Note that I'm not too clear how valuable this would be. Just asking why that isn't a valid path.)

Re:Fast midpoint between two integers without overflow by IncRnd on Wednesday December 07, 2022 @04:07PM (#33900258)
> No, you’d need an Int19.

No, that's completely false. You don't need an Int19 but an Int1.

Re:Fast midpoint between two integers without overflow by Aaargh20318 on Wednesday December 07, 2022 @05:12PM (#33901074)
How do you figure that you can store the result of adding 2 Int18s in an Int1 ? Remember, we’re talking about static types and you don’t know the values at compile time.
Re:Fast midpoint between two integers without overflow by kazinator on Wednesday December 07, 2022 @09:59PM (#33903584)
Static languages can have types which have an unboxed value part (of fixed size) that manages a boxed heap part.

  class bignum {
  private:
    digit_t *limbs;
  public:
    bignum(int val);
    ~bignum();
    bignum operator +(const bignum &rhs);
    ...
  };
Re:Fast midpoint between two integers without overflow by andrewla on Wednesday December 07, 2022 @12:28PM (#33897248)
> Since the width of the operands are known ahead of time

Not so for loops and accumulator constructs.

Re:Fast midpoint between two integers without overflow by jcparkyn on Wednesday December 07, 2022 @03:28PM (#33899793)
I think it would be reasonable to also have overflowing and checked versions of the operators, for cases where the compiler can't guarantee the size (e.g. mutable variables in loops).
Re:Fast midpoint between two integers without overflow by munificent on Wednesday December 07, 2022 @02:38PM (#33899125)
> Since the width of the operands are known ahead of time, a wider integer can be unconditionally reserved on the stack for the result of the operation.

What is the width of `i` in:

    foo(int count) {
      int i = 0;
      for (int j = 0; j < count; j++) {
        i = i + i;
      }
    }
Re:Fast midpoint between two integers without overflow by zmgsabst on Wednesday December 07, 2022 @03:14PM (#33899615)
You probably want i=1 since i=0 is an answer you can predict:

i = 0 implies that i = 0 + 0 = 0; so the loop doesn’t evolve, and the whole thing can be optimized to just i = 0.

For i=1, the loop simplifies to 2^count and a count-length type, which is the point I think you wanted.

Re:Fast midpoint between two integers without overflow by munificent on Thursday December 08, 2022 @12:56PM (#33910895)
Heh, oops, yes. :)
Re:Fast midpoint between two integers without overflow by hansvm on Wednesday December 07, 2022 @10:00AM (#33895048)
Python, common lisp, and perl for starters.
Re:Fast midpoint between two integers without overflow by pacaro on Wednesday December 07, 2022 @11:35AM (#33896439)
Also scheme and prolog

The problem you can then run into is that a mathematical operation can OOM

Re:Fast midpoint between two integers without overflow by kazinator on Wednesday December 07, 2022 @10:05PM (#33903626)
I've not seen this in practice.

You need some numeric accident involving a higher power operator like exponentiation.

In TXR Lisp I made exponentiation n-ary: you can do (expt x y z ...).

The associativity is right to left: it means

         ...
       z
     y
   x
rather than the less useful cumulative exponentiation of the same base:

  yz...
 x 
which can easily be obtained as (expt x (* y z ..)).

So, anyway, if you apply expt to small list of small operands, you can cons up a big number in rather a hurry.

If it is important to prevent a problem like this, a limit can be imposed on bignums (say, large enough for common cryptography to still work).

Re:Fast midpoint between two integers without overflow by webstrand on Wednesday December 07, 2022 @10:30AM (#33895463)
I didn't know python could do that, that's pretty cool.

I gotta disagree on perl, though, even though it can represent numbers outside of the range of a double, it can't manipulate them without converting them into doubles.

Re:Fast midpoint between two integers without overflow by Sesse__ on Wednesday December 07, 2022 @11:42AM (#33896558)
“use bignum;” and you can.