গড় 3 দীর্ঘ পূর্ণসংখ্যার


103

আমার কাছে 3 খুব বড় স্বাক্ষরিত পূর্ণসংখ্যা রয়েছে।

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

আমি তাদের কাটা গড়ের গণনা করতে চাই। প্রত্যাশিত গড় মান long.MaxValue - 1যা হয় 9223372036854775806

এটি হিসাবে গণনা করা অসম্ভব:

long avg = (x + y + z) / 3; // 3074457345618258600

দ্রষ্টব্য: আমি 2 টি গড়ে 2 টি সংখ্যা সম্পর্কে এই সমস্ত প্রশ্নটি পড়েছি, তবে কীভাবে এই প্রযুক্তিটি 3 টি গড়তে প্রয়োগ করা যেতে পারে তা আমি দেখতে পাই না।

এটি ব্যবহারের সাথে খুব সহজ হবে BigInteger, তবে ধরা যাক আমি এটি ব্যবহার করতে পারি না।

BigInteger bx = new BigInteger(x);
BigInteger by = new BigInteger(y);
BigInteger bz = new BigInteger(z);
BigInteger bavg = (bx + by + bz) / 3; // 9223372036854775806

আমি যদি রূপান্তর করি doubleতবে অবশ্যই আমি নির্ভুলতা হারাচ্ছি:

double dx = x;
double dy = y;
double dz = z;
double davg = (dx + dy + dz) / 3; // 9223372036854780000

যদি আমি রূপান্তর করি decimalতবে এটি কার্যকর হয় তবে ধরে নেওয়া যাক আমি এটি ব্যবহার করতে পারি না।

decimal mx = x;
decimal my = y;
decimal mz = z;
decimal mavg = (mx + my + mz) / 3; // 9223372036854775806

প্রশ্ন: কেবলমাত্র longটাইপ ব্যবহারের সাথে খুব সহজেই 3 টি খুব বড় পূর্ণসংখ্যার কাটা যাওয়ার কোনও উপায় আছে ? এই প্রশ্নটিকে সি # -রূপে বিবেচনা করবেন না, কেবল # সি-তে নমুনা সরবরাহ করা আমার পক্ষে সহজ।


1
কেন সামগ্রিক গড়ের পার্থক্য গণনা করা হয় না এবং সর্বাধিক থেকে বিয়োগ করা হয়?
Andreas Niedermair

6
@ আন্ড্রেসনিডেরমায়ার আমার সাথে মান long.MinValueএবং long.MaxValueমানগুলির মধ্যে কাজ করবে না ।
উলুগব্যাক উমিরভ

ভাল ক্যাচ, সত্যিই :)
Andreas Niedermair

আপনি কি নিশ্চিত যে আমাদের এটি নিয়ে চিন্তিত হওয়া দরকার, এটিকে ফ্রেমওয়ার্কের মাধ্যমে পরিচালনা করা উচিত নয়?
বলু

11
এর কোন আসল কারণ আছে BigIntegerবা decimalবাদ গেছে, বা এটি কেবল এটিকে শক্ত করার পক্ষে?
jpmc26

উত্তর:


142

এই কোডটি কাজ করবে, তবে এটি সুন্দর নয়।

এটি প্রথমে তিনটি মানকে ভাগ করে দেয় (এটি মানগুলি মেঝেতে ফেলে দেয়, সুতরাং আপনি অবশিষ্টটিকে 'হারাবেন') এবং তারপরে বাকী অংশগুলি ভাগ করে দেয়:

long n = x / 3
         + y / 3
         + z / 3
         + ( x % 3
             + y % 3
             + z % 3
           ) / 3

মনে রাখবেন যে এক বা একাধিক নেতিবাচক মান থাকার পরে উপরের নমুনাটি সর্বদা সঠিকভাবে কাজ করে না।

উলুগবাকের সাথে আলোচিত হিসাবে, যেহেতু নীচের মন্তব্যের সংখ্যাটি বিস্ফোরিত হচ্ছে, ইতিবাচক এবং নেতিবাচক উভয় মানের জন্য এখানে বর্তমান সেরা সমাধান is

উত্তর এবং মন্তব্য ধন্যবাদ Ulugbek Umirov , জেমস এস , KevinZ , মার্ক ভ্যান Leeuwen , gnasher729 এই বর্তমান সমাধান:

static long CalculateAverage(long x, long y, long z)
{
    return (x % 3 + y % 3 + z % 3 + 6) / 3 - 2
            + x / 3 + y / 3 + z / 3;
}

static long CalculateAverage(params long[] arr)
{
    int count = arr.Length;
    return (arr.Sum(n => n % count) + count * (count - 1)) / count - (count - 1)
           + arr.Sum(n => n / count);
}

3
@ ডেভিডজি নং গণিতে (x + y + z) / 3 = x / 3 + y / 3 + z / 3,।
ক্রিস ভ্যান্ডারমোটেন

4
আমি 1 এবং 5. মধ্যে সব পরিবর্তনশীল গন্য এই সঠিক প্রমাণ করার জন্য Z3 ব্যবহৃত
usr ডিরেক্টরির

5
অবশ্যই এটি কাজ করে বলে মনে হচ্ছে, তবে যেভাবে পূর্ণসংখ্যার কাটা কাজ চালাচ্ছে তা আপনাকে ছড়িয়ে দেবে। f(1,1,2) == 1যখনf(-2,-2,8) == 2
কেভিনজেড

11
নোট করুন যে মডিউল অপারেশনের মস্তিষ্ক-ক্ষতিগ্রস্থ শব্দার্থতন্ত্রের কারণে, ভেরিয়েবলের জন্য নেতিবাচক মানগুলি অনুমোদিত হলে, এটি একের পর এক বন্ধ হয়ে যায়, নামিয়ে না দিয়ে গোল করে result উদাহরণস্বরূপ, যদি x, y 3 এর গুণক গুণক হয়, এবং z -2 হয় তবে আপনি এটি পেতে পারেন (x+y)/3যা খুব বেশি।
মার্ক ভ্যান লিউউইন

6
@ কেভিনজেড: ... যার প্রভাব তখন কোনও প্রোগ্রামার দ্বারা বাতিল করা উচিত যারা এই বিশেষ ক্ষেত্রে আচরণটি প্রথম স্থানে চায়নি। প্রোগ্রামারটি মডুলাস নির্দিষ্ট করে দেওয়া বাদ দিয়ে অন্যটি থেকে নেওয়া যা সংকলকটি মডুলাস থেকে উদ্ভূত হতে পারে তা সহায়ক বলে মনে হয়।
সুপারক্যাট

26

এনবি - প্যাট্রিক ইতিমধ্যে দুর্দান্ত উত্তর দিয়েছেন । এটি প্রসারিত করে আপনি এর মতো সংখ্যক পূর্ণসংখ্যার জন্য জেনেরিক সংস্করণ করতে পারেন:

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

long[] arr = { x, y, z };
var avg = arr.Select(i => i / arr.Length).Sum() 
        + arr.Select(i => i % arr.Length).Sum() / arr.Length;

1
এটি ঘটবে না long, তবে ছোট ধরণের ক্ষেত্রে লক্ষ্য করুন যে দ্বিতীয় যোগটি প্রবাহিত হতে পারে।
user541686

7

প্যাট্রিক হফম্যান একটি দুর্দান্ত সমাধান পোস্ট করেছেন । তবে প্রয়োজনে এটি আরও বেশ কয়েকটি উপায়ে প্রয়োগ করা যেতে পারে। এখানে অ্যালগরিদম ব্যবহার করে আমার আরও একটি সমাধান রয়েছে। যদি সাবধানে প্রয়োগ করা হয় তবে ধীর হার্ডওয়্যার বিভাজনকারী সিস্টেমে একাধিক বিভাগের চেয়ে এটি দ্রুত হতে পারে। এটি হ্যাকারের আনন্দের বিষয় থেকে ধ্রুবক প্রযুক্তি দ্বারা বিভাজন ব্যবহার করে আরও অনুকূলিত করা যায়

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;

সি / সি ++ এ -৪-বিট প্ল্যাটফর্মগুলিতে এটি আরও সহজ __int128

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

2
আমি প্রস্তাব দিচ্ছি যে 32-বিট স্বাক্ষরিত মানকে 3 দ্বারা ভাগ করার একটি ভাল উপায় হ'ল 0x55555555L দ্বারা গুন করা, 0x55555555 যুক্ত করা এবং সরাসরি 32 দ্বারা স্থানান্তর করা Your
সুপারক্যাট

@ সুপের্যাট হ্যাঁ আমি সেই পদ্ধতিটি জানি। হ্যাকারের আনন্দের পদ্ধতিটি আরও সঠিক তবে আমি আবারও বাস্তবায়ন করব
ফুচলভ

"আরও সঠিক" এর অর্থ কী তা আমি নিশ্চিত নই। পারস্পরিক ক্রিয়াকলাপ অনেক ক্ষেত্রে সরাসরি সঠিক মান অর্জন করতে পারে, না হলে ফলন মানগুলি এক বা দুটি ধাপে পরিমার্জনযোগ্য হতে পারে। বিটিডাব্লু, আমি মনে করি আমার 0x55555556 দ্বারা গুণ করার পরামর্শ দেওয়া উচিত ছিল, যা "অ্যাড" এর প্রয়োজন ছাড়াই সঠিক ফলাফল পেতে পারে। এছাড়াও, আপনার লুপের অবস্থাটি কি সঠিক? লুপে এইচ এবং এল কে কী পরিবর্তন করে?
সুপারক্যাট

ঘটনাচক্রে, এমনকি যদি কারও কাছে একটি হার্ডওয়্যার গুণিত না থাকে তবে দ্রুত একটি স্বাক্ষরবিহীন x=y/3মাধ্যমে প্রায় অনুমান করা যায় x=y>>2; x+=x>>2; x+=x>>4; x+=x>>8; x+=x>>16; x+=x>>32;। ফলাফলটি এক্সের খুব কাছাকাছি থাকবে এবং গণনা করে delta=y-x-x-x;এবং xপ্রয়োজনীয়তা অনুযায়ী সামঞ্জস্য করে সুনির্দিষ্ট করা যায় ।
সুপারক্যাট

1
@ gnasher729 আমি অবাক হয়েছি যে এটি 32-বিট কম্পিউটারগুলিতে সেই অপ্টিমাইজেশনটি ব্যবহার করতে পারে যেহেতু এটি প্রায়শই 64x64 → 128 বিট গুণ করতে পারে না
ফুক্লভি

7

যোগফলটি ব্যবহার না করে আপনি সংখ্যাগুলির পার্থক্যের ভিত্তিতে সংখ্যার গড় গণনা করতে পারেন।

ধরা যাক এক্স হ'ল সর্বাধিক, y হ'ল মিডিয়ান, z হ'ল মিনিট (যেমন আপনার আছে)। আমরা তাদের সর্বাধিক, মধ্যমা এবং ন্যূনতম বলব।

@ উলুগব্যাক উমিরভের মন্তব্য অনুসারে শর্তসাপেক্ষ পরীক্ষক যুক্ত হয়েছে:

long tmp = median + ((min - median) / 2);            //Average of min 2 values
if (median > 0) tmp = median + ((max - median) / 2); //Average of max 2 values
long mean;
if (min > 0) {
    mean = min + ((tmp - min) * (2.0 / 3)); //Average of all 3 values
} else if (median > 0) {
    mean = min;
    while (mean != tmp) {
        mean += 2;
        tmp--;
    }
} else if (max > 0) {
    mean = max;
    while (mean != tmp) {
        mean--;
        tmp += 2;
    }
} else {
    mean = max + ((tmp - max) * (2.0 / 3));
}

2
@ UlugbekUmirov এর মন্তব্য দেখুন: হায় ক্ষেত্রে কাজ করে না যদি আমি long.MinValue এবং long.MaxValue আছে মূল্যবোধের মধ্যে
Bolu- এর

@ বলু মন্তব্যটি কেবল দীর্ঘের ক্ষেত্রে প্রযোজ্য inমিনভ্যালু। সুতরাং আমি এটি শর্তসাপেক্ষে যুক্ত করেছি যাতে এটি আমাদের ক্ষেত্রে কাজ করে।
লা-কোমাদ্রেজা

আপনি যখন মিডিয়ানাটি আরম্ভ করা হয়নি তখন কীভাবে ব্যবহার করতে পারেন?
ফুকলিভ

@ LưuVĩnhPhúc, মিডিয়ান হ'ল ন্যূনতম এবং সর্বাধিকের মধ্যে মান।
লা-কোমড্রেজা

1
(double)(2 / 3)0.0 এর সমান নয় ?
ফুক্লভ

5

যেহেতু সি ইউক্লিডিয়ান বিভাগের পরিবর্তে তলভিত্তিক বিভাগ ব্যবহার করে, তিনটি স্বাক্ষরিত মানগুলির চেয়ে তিনটি স্বাক্ষরিত মানগুলির সঠিকভাবে গোলাকার গড় গণনা করা আরও সহজ। স্বাক্ষরিত স্বাক্ষরিত গড় নেওয়ার আগে প্রতিটি সংখ্যায় কেবল 0x8000000000000000UL যুক্ত করুন, ফলাফল নেওয়ার পরে এটি বিয়োগ করুন এবং স্বাক্ষরিত গড় পাওয়ার জন্য একটি চেক না করা কাস্ট ব্যবহার করুন Int64

স্বাক্ষরবিহীন গড় গণনা করতে, তিনটি মানের শীর্ষ 32 বিটের যোগফল গণনা করুন। তারপরে তিনটি মানের নীচের 32 টি বিটের যোগফল, এবং উপরের সমষ্টি, এক এবং আরও একটি যোগফলকে গোলাকার ফলাফল দেবে] ute প্রথম যোগফলের গড় 0x55555555 গুণ হবে, এবং দ্বিতীয়টির এক তৃতীয়াংশ।

৩২-বিট প্রসেসরের উপর পারফরম্যান্স তিনটি "যোগফল" মান যার প্রতিটি 32 টি বিট দীর্ঘ, উত্পাদন করে বাড়ানো যেতে পারে যাতে চূড়ান্ত ফলাফল হয় ((0x55555555UL * sumX)<<32) + 0x55555555UL * sumH + sumL/3; এটি সম্ভবত প্রতিস্থাপনের sumL/3মাধ্যমে আরও বাড়ানো যেতে পারে ((sumL * 0x55555556UL) >> 32), যদিও পরবর্তীকালেটি জেআইটি অপ্টিমাইজারের উপর নির্ভর করবে [এটি হয়ত বুঝতে পারে কীভাবে একটি গুণকে 3 দ্বারা বিভাজন প্রতিস্থাপন করতে হবে, এবং এর কোডটি সম্ভবত একটি সুস্পষ্ট গুণিত ক্রিয়াকলাপের চেয়ে আরও কার্যকর হতে পারে]।


0x8000000000000000UL যুক্ত করার পরে ওভারফ্লো ফলাফলটিকে প্রভাবিত করে না?
ফুকলিভ

@ LưuVĩnhPhúc- এর কোনও ওভারফ্লো নেই। একটি প্রয়োগের জন্য আমার উত্তর যান । 2 32 বিট ইন্টিতে বিভক্ত হওয়া অপ্রয়োজনীয় ছিল।
কেভিনজেড

@ কেভিনজেড: প্রতিটি মানকে একটি উপরের এবং নিম্ন 32-বিট অংশে বিভক্ত করা বিভক্ত হওয়ার চেয়ে তিনটি ভাগ এবং বাকী অংশে ভাগ করার চেয়ে দ্রুত than
সুপারক্যাট

1
@ লুভানহ্ফ্যাক: স্বাক্ষরিত মানগুলির মতো নয় যা সংখ্যার মতো শব্দার্থকভাবে আচরণ করে এবং কোনও বৈধ সি প্রোগ্রামে উপচে পড়ার অনুমতি নেই, স্বাক্ষরযুক্ত মানগুলি সাধারণত মোড়কানো বিমূর্ত বীজগণিত রিংয়ের সদস্যদের মতো আচরণ করে, তাই মোড়ানো শব্দার্থকগুলি সঠিকভাবে সংজ্ঞায়িত হয়েছে।
সুপারক্যাট

1
টিপল -3, -2, -1 উপস্থাপন করে। প্রতিটি মান 0x8000U যোগ করার পরে, মানগুলি পরে অর্ধেক করা উচিত: 7F + FF 7F + FE 7F + FD। 17 ডি + 2 এফএ ফলন করে উপরের এবং নীচের অংশগুলিকে যুক্ত করুন। 477 ফলন পাওয়া নীচের অর্ধের যোগফলের শীর্ষ-অর্ধের যোগফল যোগ করুন 55 55 টি 7E81 উপার্জন দ্বারা 17 ডি গুণ করুন। তিনটি উত্পাদক 17 ডি দিয়ে 477 ভাগ করুন। 7F8 ফলনশীল 17D এ 7E81 যুক্ত করুন। এটি থেকে 8000 বিয়োগ করুন এবং -2 পান।
সুপারক্যাট

5

প্যাট্রিক হফম্যানের সমাধানটিকে সুপারকার্টের সংশোধন সহ প্যাচিং করছি, আমি আপনাকে নিম্নলিখিতটি দিচ্ছি:

static Int64 Avg3 ( Int64 x, Int64 y, Int64 z )
{
    UInt64 flag = 1ul << 63;
    UInt64 x_ = flag ^ (UInt64) x;
    UInt64 y_ = flag ^ (UInt64) y;
    UInt64 z_ = flag ^ (UInt64) z;
    UInt64 quotient = x_ / 3ul + y_ / 3ul + z_ / 3ul
        + ( x_ % 3ul + y_ % 3ul + z_ % 3ul ) / 3ul;
    return (Int64) (quotient ^ flag);
}

এবং এন উপাদান কেস:

static Int64 AvgN ( params Int64 [ ] args )
{
    UInt64 length = (UInt64) args.Length;
    UInt64 flag = 1ul << 63;
    UInt64 quotient_sum = 0;
    UInt64 remainder_sum = 0;
    foreach ( Int64 item in args )
    {
        UInt64 uitem = flag ^ (UInt64) item;
        quotient_sum += uitem / length;
        remainder_sum += uitem % length;
    }

    return (Int64) ( flag ^ ( quotient_sum + remainder_sum / length ) );
}

এটি সর্বদা গড়ের তলটি () দেয় এবং প্রতিটি সম্ভাব্য প্রান্তের কেসটি সরিয়ে দেয়।


1
আমি এডজিএন কে জেড 3 কোডে অনুবাদ করেছি এবং সমস্ত যুক্তিসঙ্গত ইনপুট মাপের জন্য এটি সঠিক প্রমাণ করেছি (উদাহরণস্বরূপ 1 <= আরগস L দৈর্ঘ্য <= 5 এবং 6 এর বিটভেটার আকার)। এই উত্তরটি সঠিক।
usr

আশ্চর্য উত্তর কেভিন। আপনার অবদানের জন্য ধন্যবাদ! meta.stackoverflow.com/a/303292/993547
প্যাট্রিক

4

আপনি প্রতিটি সংখ্যা লিখতে পারবেন এই সত্যটি ব্যবহার করতে পারেন y = ax + b, যেখানে xধ্রুবক রয়েছে। প্রতিটি aহবে y / x(বিভাগের পূর্ণসংখ্যার অংশ)। প্রতিটি খ হবে y % x(বিভাগের বাকি / মডুলো)। আপনি যদি এই ধ্রুবকটিকে বুদ্ধিমান উপায়ে বেছে নেন, উদাহরণস্বরূপ, ধ্রুবক হিসাবে সর্বাধিক সংখ্যার বর্গমূলকে বেছে নিয়ে, আপনি xওভারফ্লোতে সমস্যা না করে গড়ে গড় সংখ্যা পেতে পারেন ।

সংখ্যার একটি স্বেচ্ছাসেবীর তালিকার গড়ের সন্ধান পাওয়া যাবে:

( ( sum( all A's ) / length ) * constant ) + 
( ( sum( all A's ) % length ) * constant / length) +
( ( sum( all B's ) / length )

যেখানে %মডুলো /বোঝায় এবং বিভাগটির 'পুরো' অংশকে বোঝায়।

প্রোগ্রামটি দেখতে এমন কিছু হবে:

class Program
{
    static void Main()
    {
        List<long> list = new List<long>();
        list.Add( long.MaxValue );
        list.Add( long.MaxValue - 1 );
        list.Add( long.MaxValue - 2 );

        long sumA = 0, sumB = 0;
        long res1, res2, res3;
        //You should calculate the following dynamically
        long constant = 1753413056;

        foreach (long num in list)
        {
            sumA += num / constant;
            sumB += num % constant;
        }

        res1 = (sumA / list.Count) * constant;
        res2 = ((sumA % list.Count) * constant) / list.Count;
        res3 = sumB / list.Count;

        Console.WriteLine( res1 + res2 + res3 );
    }
}

4

যদি আপনি জানেন যে আপনার এন মান রয়েছে তবে আপনি কি প্রতিটি মানকে N দ্বারা ভাগ করে একসাথে যোগ করতে পারেন?

long GetAverage(long* arrayVals, int n)
{
    long avg = 0;
    long rem = 0;

    for(int i=0; i<n; ++i)
    {
        avg += arrayVals[i] / n;
        rem += arrayVals[i] % n;
    }

    return avg + (rem / n);
}

এটি প্যাট্রিক হফম্যানের সমাধানের মতোই, চূড়ান্ত সংস্করণটি যদি কম সঠিক না হয়
ফুচলভি

2

আমি এটিও চেষ্টা করেছি এবং একটি দ্রুত সমাধান নিয়ে এসেছি (যদিও এটি কেবল 3/4 সম্পর্কে একটি উপাদান দ্বারা)। এটি একটি একক বিভাগ ব্যবহার করে

public static long avg(long a, long b, long c) {
    final long quarterSum = (a>>2) + (b>>2) + (c>>2);
    final long lowSum = (a&3) + (b&3) + (c&3);
    final long twelfth = quarterSum / 3;
    final long quarterRemainder = quarterSum - 3*twelfth;
    final long adjustment = smallDiv3(lowSum + 4*quarterRemainder);
    return 4*twelfth + adjustment;
}

যেখানে smallDiv3গুণিতক ব্যবহার করে 3 দ্বারা বিভাজন হয় এবং কেবলমাত্র ছোট যুক্তির জন্য কাজ করে

private static long smallDiv3(long n) {
    assert -30 <= n && n <= 30;
    // Constants found rather experimentally.
    return (64/3*n + 10) >> 6;
}

এখানে একটি পরীক্ষা এবং একটি মানদণ্ড সহ পুরো কোডটি দেওয়া আছে , ফলাফলগুলি তেমন চিত্তাকর্ষক নয়।


1

এই ফাংশনটি দুটি বিভাগে ফলাফল গণনা করে। এটি অন্যান্য বিভাজনকারী এবং শব্দের আকারের জন্য দুর্দান্তভাবে সাধারণীকরণ করা উচিত।

এটি দ্বি-শব্দ সংযোজন ফলাফল গণনা করে কাজ করে, তারপরে বিভাগটি কাজ করে।

Int64 average(Int64 a, Int64 b, Int64 c) {
    // constants: 0x10000000000000000 div/mod 3
    const Int64 hdiv3 = UInt64(-3) / 3 + 1;
    const Int64 hmod3 = UInt64(-3) % 3;

    // compute the signed double-word addition result in hi:lo
    UInt64 lo = a; Int64 hi = a>=0 ? 0 : -1;
    lo += b; hi += b>=0 ? lo<b : -(lo>=UInt64(b));
    lo += c; hi += c>=0 ? lo<c : -(lo>=UInt64(c));

    // divide, do a correction when high/low modulos add up
    return hi>=0 ? lo/3 + hi*hdiv3 + (lo%3 + hi*hmod3)/3
                 : lo/3+1 + hi*hdiv3 + Int64(lo%3-3 + hi*hmod3)/3;
}

0

ম্যাথ

(x + y + z) / 3 = x/3 + y/3 + z/3

(a[1] + a[2] + .. + a[k]) / k = a[1]/k + a[2]/k + .. + a[k]/k

কোড

long calculateAverage (long a [])
{
    double average = 0;

    foreach (long x in a)
        average += (Convert.ToDouble(x)/Convert.ToDouble(a.Length));

    return Convert.ToInt64(Math.Round(average));
}

long calculateAverage_Safe (long a [])
{
    double average = 0;
    double b = 0;

    foreach (long x in a)
    {
        b = (Convert.ToDouble(x)/Convert.ToDouble(a.Length));

        if (b >= (Convert.ToDouble(long.MaxValue)-average))
            throw new OverflowException ();

        average += b;
    }

    return Convert.ToInt64(Math.Round(average));
}

{1,2,3}উত্তরটির সেটটি থাকলেও 2আপনার কোডটি ফিরে আসবে 1
উলুগব্যাক উমিরভ

@ অলগবাক উমিরভ কোড ঠিক করা হয়েছে, প্রসেসিংয়ের জন্য দ্বিগুণ প্রকার ব্যবহার করা উচিত
খালেদ.কে

1
এটাই আমি এড়াতে চাই - এর ব্যবহার double, যেহেতু আমরা এই ক্ষেত্রে নির্ভুলতা হারাতে চাই।
উলুগব্যাক উমিরভ

0

এটা চেষ্টা কর:

long n = Array.ConvertAll(new[]{x,y,z},v=>v/3).Sum()
     +  (Array.ConvertAll(new[]{x,y,z},v=>v%3).Sum() / 3);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.