Average of 3 long integers

前端 未结 12 1745
我寻月下人不归
我寻月下人不归 2020-12-07 10:05

I have 3 very large signed integers.

long x = long.MaxValue;
long y = long.MaxValue - 1;
long z = long.MaxValue - 2;

I want to calculate th

12条回答
  •  孤城傲影
    2020-12-07 11:09

    Patrick Hofman has posted a great solution. But if needed it can still be implemented in several other ways. Using the algorithm here I have another solution. If implemented carefully it may be faster than the multiple divisions in systems with slow hardware divisors. It can be further optimized by using divide by constants technique from hacker's delight

    public class int128_t {
        private int H;
        private long L;
    
        public int128_t(int h, long l)
        {
            H = h;
            L = l;
        }
    
        public int128_t add(int128_t a)
        {
            int128_t s;
            s.L = L + a.L;
            s.H = H + a.H + (s.L < a.L);
            return b;
        }
    
        private int128_t rshift2()  // right shift 2
        {
            int128_t r;
            r.H = H >> 2;
            r.L = (L >> 2) | ((H & 0x03) << 62);
            return r;
        }
    
        public int128_t divideby3()
        {
            int128_t sum = {0, 0}, num = new int128_t(H, L);
            while (num.H || num.L > 3)
            {
                int128_t n_sar2 = num.rshift2();
                sum = add(n_sar2, sum);
                num = add(n_sar2, new int128_t(0, num.L & 3));
            }
    
            if (num.H == 0 && num.L == 3)
            {
                // sum = add(sum, 1);
                sum.L++;
                if (sum.L == 0) sum.H++;
            }
            return sum; 
        }
    };
    
    int128_t t = new int128_t(0, x);
    t = t.add(new int128_t(0, y));
    t = t.add(new int128_t(0, z));
    t = t.divideby3();
    long average = t.L;
    

    In C/C++ on 64-bit platforms it's much easier with __int128

    int64_t average = ((__int128)x + y + z)/3;
    

提交回复
热议问题