সি ++: একটি সংখ্যার নিকটতম একাধিক পর্যন্ত গোলাকার


168

ঠিক আছে - এটি এখানে পোস্ট করাতে আমি প্রায় বিব্রত বোধ করছি (এবং যদি কেউ বন্ধ করার পক্ষে ভোট দেয় তবে আমি মুছে ফেলব) যেমন এটি কোনও প্রাথমিক প্রশ্নের মতো মনে হয়।

এটি কি সি ++ এর সংখ্যার একাধিক পর্যন্ত গোল করার সঠিক উপায়?

আমি জানি যে এ সম্পর্কিত অন্যান্য প্রশ্ন রয়েছে তবে আমি সি ++ এ করার সর্বোত্তম উপায় কী তা জানতে আগ্রহী am

int roundUp(int numToRound, int multiple)
{
 if(multiple == 0)
 {
  return numToRound;
 }

 int roundDown = ( (int) (numToRound) / multiple) * multiple;
 int roundUp = roundDown + multiple; 
 int roundCalc = roundUp;
 return (roundCalc);
}

আপডেট: দুঃখিত আমি সম্ভবত উদ্দেশ্যটি পরিষ্কার করেছিলাম না। এখানে কিছু উদাহরন:

roundUp(7, 100)
//return 100

roundUp(117, 100)
//return 200

roundUp(477, 100)
//return 500

roundUp(1077, 100)
//return 1100

roundUp(52, 20)
//return 60

roundUp(74, 30)
//return 90

3
আপনার যুক্তিতে আপনার একটি ত্রুটি রয়েছে - আসুন আমি বলি যে আমি 4 এর নিকটতম 2 এর ২ টি গোল করতে চাই to রাউন্ডডাউন = (4/2) * 2 = 4; roundUp = 4 + 2; সুতরাং roundCalc = 6. আমি ধরে নিচ্ছি যে আপনি সেই ক্ষেত্রে 4 ফিরে আসতে চান।
নিকি যোশিউচি

এটি রাউন্ডআপ (30,30) এর জন্য কাজ করে না। এটি উত্তর হিসাবে 60 দেয়, এখনও উত্তর হিসাবে 30 দেওয়া উচিত ..
বসোবাইদ

@ বসোবাইদ: নীচে আমার উত্তরটি দেখুন। এটি এখানে অন্যান্য সমাধানগুলির তুলনায় কিছুটা সহজ, যদিও সেগুলি খুব কার্যকর হওয়া উচিত
নিক্লাস বি।

3
আপনার পরীক্ষার ক্ষেত্রে লক্ষণীয়ভাবে ঋণাত্মক সংখ্যা, ক্ষেত্রে যেখানে বিভাজন সঠিক হয়, ক্ষেত্রে যেখানে বিভাজন প্রায় সঠিক, এবং মামলা জড়িত উদাহরণ অনুপস্থিত যেখানে সংখ্যার খুব পরিসীমা সীমা কাছাকাছি হয় int

1
রববেন_ফোর্ড_ ফ্যান_বয়, আপনি যে উত্তরটি দিয়েছিলেন তা সম্পাদনা সরানো উচিত। যদি দেওয়া উত্তরগুলির থেকে পৃথক হয় তবে আপনি নিজের উত্তর পোস্ট করতে পারেন। যেমনটি দাঁড়িয়েছে, সেই উত্তরের এমন সমস্যা রয়েছে যা উত্তর বিভাগে সম্বোধন করা উচিত।
chux - মনিকা পুনরায় ইনস্টল করুন

উত্তর:


161

এটি ইতিবাচক সংখ্যার জন্য কাজ করে, নেতিবাচক সম্পর্কে নিশ্চিত নয়। এটি কেবল পূর্ণসংখ্যার গণিত ব্যবহার করে।

int roundUp(int numToRound, int multiple)
{
    if (multiple == 0)
        return numToRound;

    int remainder = numToRound % multiple;
    if (remainder == 0)
        return numToRound;

    return numToRound + multiple - remainder;
}

সম্পাদনা করুন: এখানে এমন একটি সংস্করণ যা নেতিবাচক সংখ্যার সাথে কাজ করে, যদি "আপ" দ্বারা আপনি সর্বদা> = ইনপুট এমন একটি ফলাফল বোঝান।

int roundUp(int numToRound, int multiple)
{
    if (multiple == 0)
        return numToRound;

    int remainder = abs(numToRound) % multiple;
    if (remainder == 0)
        return numToRound;

    if (numToRound < 0)
        return -(abs(numToRound) - remainder);
    else
        return numToRound + multiple - remainder;
}

+1 আমার মতে, অবশ্যই সর্বোত্তম এবং সবচেয়ে পঠনযোগ্য সমাধান।
রববেন_ফোর্ড_ ফ্যান_বয়

1
if(number<0){ multiple = multiple*(-1); }ডান দিকের নেতিবাচক সংখ্যার বৃত্তাকার শুরুতে যুক্ত করুন
জোশ

4
@ জোশ: কেন গুণ? if(number<0) multiple = -multipleসহজ।
এমডি 5

এটি রাউন্ডআপ (30,30) এর জন্য কাজ করে না। এটি উত্তর হিসাবে 60 দেয়, এটি এখনও উত্তর হিসাবে 30 দেওয়া উচিত।
বসোবাইদ

@bsobaid অসম্ভব। if (remainder == 0)পরীক্ষা যে ক্ষেত্রে যত্ন নিতে হবে। এটি আমার পক্ষে কাজ করে: ideone.com/Waol7B
মার্ক র্যানসোম

112

শর্ত ছাড়াই:

int roundUp(int numToRound, int multiple) 
{
    assert(multiple);
    return ((numToRound + multiple - 1) / multiple) * multiple;
}

এটি শূন্য থেকে দূরে গোল করার মতো কাজ করে নেতিবাচক সংখ্যার জন্য

সম্পাদনা: এমন সংস্করণ যা নেতিবাচক সংখ্যার জন্যও কাজ করে

int roundUp(int numToRound, int multiple) 
{
    assert(multiple);
    int isPositive = (int)(numToRound >= 0);
    return ((numToRound + isPositive * (multiple - 1)) / multiple) * multiple;
}

টেস্ট


যদি multiple2 এর শক্তি হয় (দ্রুত qu 3.7 বারে http://quick-bench.com/sgPEZV9AUDqtx2uujRSa3-eTE80 )

int roundUp(int numToRound, int multiple) 
{
    assert(multiple && ((multiple & (multiple - 1)) == 0));
    return (numToRound + multiple - 1) & -multiple;
}

টেস্ট


24
2 সংস্করণের পাওয়ারের জন্য +1। এটি কার্যকর হিসাবে এটি সম্পূর্ণরূপে গুণ, বিভাগ বা মডুলোর ব্যয় এড়িয়ে চলে।
নিকস সি

আপনি কি নিশ্চিত যে এই অ্যালগরিদমের কোনও পূর্বশর্ত নেই? নেতিবাচক সংখ্যা সম্পর্কে কি? আচরণটি প্রাক-সি ++ 11 এ অপরিজ্ঞাত বলে মনে হচ্ছে
কিউবসস্প্ল 42

> নেতিবাচক সংখ্যা সম্পর্কে কি? বর্ণিত হিসাবে, এটি শূন্য থেকে দূরে গোল করার মতো নেতিবাচক সংখ্যার জন্য কাজ করে।
KindDragon

আমি শূন্য থেকে দূরে না, ইতিবাচক অনন্তের দিকে গোলাকার অর্থ "রাউন্ড আপ" পড়েছি।

8
নোট যে দুটি এর পরিপূরক গাণিতিক & ~(x - 1)হিসাবে একই & -x
টড লেহম্যান

39

যখন ফ্যাক্টর সর্বদা ইতিবাচক থাকবে তখন এটি কাজ করে:

int round_up(int num, int factor)
{
    return num + factor - 1 - (num - 1) % factor;
}

সম্পাদনা: এটি ফিরে আসে round_up(0,100)=100। ফিরে আসার সমাধানের জন্য দয়া করে নীচে পলের মন্তব্য দেখুন round_up(0,100)=0


1
'ইতিমধ্যে-একাধিক' কেস পরিচালনা করে এমন সংক্ষিপ্ততম কেস বলে মনে হচ্ছে।
হারিং করুন

1
ব্যয়বহুল অপারেশনের সংখ্যার দিক থেকে সেরা সমাধান। এটি কেবলমাত্র একক বিভাজন এবং কোনও গুণ নয়
নিক্লাস বি।

3
রাউন্ড_আপ (০, ১০০) == গৃহীত উত্তরের মত 0-এর পরিবর্তে 100
গ্রেগরি

7
এটা করা উচিত নয় num + factor - 1 - (num + factor - 1) % factor?
পল

6
num - 1 - (num - 1) % factor + factorপূর্ণসংখ্যার অতিরিক্ত প্রবাহের ঝুঁকি ছাড়াই একই গণনা করে।

24

এটি "বাইট-এন কতগুলি বিট নেবে তা আমি কীভাবে খুঁজে পাব?" (এ: (এন বিটস + 7) / 8) এর সমস্যার একটি সাধারণীকরণ।

int RoundUp(int n, int roundTo)
{
    // fails on negative?  What does that mean?
    if (roundTo == 0) return 0;
    return ((n + roundTo - 1) / roundTo) * roundTo; // edit - fixed error
}

1
এটি কোনও সংখ্যার পরবর্তী একাধিক পর্যন্ত গোল হয় না।
আআআআআ বি বি বি বি

7
আমি এই সমাধানটি পছন্দ করি কারণ যদি রাউন্ডটো 2 এর শক্তি হয়ে যায়, আপনি / এবং * কে সরিয়ে সস্তার অপারেশনগুলি ছাড়া আর কিছুই শেষ করতে পারবেন না (x = রাউন্ডটো - 1; রিটার্ন (এন + এক্স) & ~ x;)
ট্রেজকাজ

পছন্দ করুন এটি (x = roundTo - 1; return (n+x)&~roundTo;)আমার উত্তরের মতো হওয়া উচিত
KindDragon

@ KindDragon আমার পক্ষে ভুল ফলাফল তৈরি করে, তবে আমি যদি ~ রাউন্ডটোর পরিবর্তে ~ x বলার জন্য এটি সংশোধন করি, তবে আমি প্রত্যাশিত ফলাফল পেয়েছি। জাভা 8 তে যাই হোক।
Trejkaz

@ কাইন্ডড্রাগন: এবং মাস্কটি হওয়া দরকার 0xFFF...000, না 0xFFF7FFFবা কিছু হতে পারে, সুতরাং আপনি 2 এর -শক্তির উপর 2 এর পরিপূরক ঘৃণা ( : বিয়োগ) বা 2 এর পাওয়ারের চেয়ে কম বিট-ফ্লিপ করতে চান (যার পরিপূরক বিপরীত ~,: টিল্ড বিয়োগ নয়)। তাই (n+x) & ~xবা (n-roundTo+1) & -roundTo
পিটার কর্ডস

14
int roundUp(int numToRound, int multiple)
{
 if(multiple == 0)
 {
  return 0;
 }
 return ((numToRound - 1) / multiple + 1) * multiple;  
}

এবং শর্তগুলি নিয়ে গণ্ডগোলের দরকার নেই


11

যে কেউ একটি সংক্ষিপ্ত এবং মিষ্টি উত্তর খুঁজছেন জন্য। এটিই আমি ব্যবহার করেছি। নেতিবাচক জন্য কোন অ্যাকাউন্টিং।

n - (n % r)

এটি আগের ফ্যাক্টরটি ফিরিয়ে দেবে।

(n + r) - (n % r)

পরের দিকে ফিরে আসবে। আশা করি এটি কাউকে সাহায্য করবে। :)


9
float roundUp(float number, float fixedBase) {
    if (fixedBase != 0 && number != 0) {
        float sign = number > 0 ? 1 : -1;
        number *= sign;
        number /= fixedBase;
        int fixedPoint = (int) ceil(number);
        number = fixedPoint * fixedBase;
        number *= sign;
    }
    return number;
}

এটি যে কোনও ফ্লোট নম্বর বা বেসের জন্য কাজ করে (উদাহরণস্বরূপ আপনি নিকটবর্তী to. round৫-এ গোল করতে পারেন)। সংক্ষেপে এটি স্থির বিন্দুতে রূপান্তরিত হয়, সেখানে গোলাকার হয়, তারপরে ফিরে রূপান্তরিত হয়। এটি 0 থেকে AWAY বৃত্তাকার করে নেতিবাচকদের পরিচালনা করে It এটি মূলত ফাংশনটিকে রাউন্ডডাউনে রূপান্তর করে একটি নেতিবাচক রাউন্ডকে মান হিসাবে পরিচালনা করে।

একটি নির্দিষ্ট নির্দিষ্ট সংস্করণ এর মতো দেখাচ্ছে:

int roundUp(int number, int fixedBase) {
    if (fixedBase != 0 && number != 0) {
        int sign = number > 0 ? 1 : -1;
        int baseSign = fixedBase > 0 ? 1 : 0;
        number *= sign;
        int fixedPoint = (number + baseSign * (fixedBase - 1)) / fixedBase;
        number = fixedPoint * fixedBase;
        number *= sign;
    }
    return number;
}

যোগ বা নেতিবাচক ইনপুট সমর্থন সহ যা কমবেশি প্লিন্থের উত্তর।


আমি ডাবল সহ ফ্লোট রাউন্ডআপ কোডটি পরীক্ষা করেছি, এটি আমার পক্ষে কাজ করে। সত্যিই আমার সমস্যা সমাধান করে।
আশিফ

1
double round(double value, double multiple) { double sign = value; multiple = std::copysign(multiple, 1.0); value = std::copysign(value, 1.0); return std::copysign(multiple * std::ceil(value / multiple), sign); }রাউন্ডিংয়ের জন্য বা স্যুপ অদলবদল সম্পর্কে কি ।
ট্রয়সিফ

8

এটি একটি টেমপ্লেট ফাংশন ব্যবহার করে আধুনিক সি ++ পদ্ধতির যা ভাসমান, ডাবল, দীর্ঘ, অন্তর্ এবং সংক্ষিপ্ত (তবে দীর্ঘ দীর্ঘ নয় এবং ব্যবহৃত দ্বিগুণ মানের কারণে দীর্ঘ দ্বিগুণ) জন্য কাজ করছে।

#include <cmath>
#include <iostream>

template<typename T>
T roundMultiple( T value, T multiple )
{
    if (multiple == 0) return value;
    return static_cast<T>(std::round(static_cast<double>(value)/static_cast<double>(multiple))*static_cast<double>(multiple));
}

int main()
{
    std::cout << roundMultiple(39298.0, 100.0) << std::endl;
    std::cout << roundMultiple(20930.0f, 1000.0f) << std::endl;
    std::cout << roundMultiple(287399, 10) << std::endl;
}

তবে আপনি নীচে দেখানো হিসাবে টেমপ্লেট বিশেষায়নের জন্য long longএবং সহজেই সমর্থন যোগ করতে পারেন long double:

template<>
long double roundMultiple<long double>( long double value, long double multiple)
{
    if (multiple == 0.0l) return value;
    return std::round(value/multiple)*multiple;
}

template<>
long long roundMultiple<long long>( long long value, long long multiple)
{
    if (multiple == 0.0l) return value;
    return static_cast<long long>(std::round(static_cast<long double>(value)/static_cast<long double>(multiple))*static_cast<long double>(multiple));
}

রাউন্ড আপ করার জন্য ফাংশন তৈরি করতে, ব্যবহার করতে std::ceilএবং সর্বদা ব্যবহারকে গোল করে ফেলার জন্য std::floor। উপরে থেকে আমার উদাহরণ ব্যবহার rounding করা হয় std::round

নীচে প্রদর্শিত হিসাবে "রাউন্ড আপ" বা আরও ভাল "রাউন্ড সিলিং" টেম্পলেট ফাংশন হিসাবে পরিচিত:

template<typename T>
T roundCeilMultiple( T value, T multiple )
{
    if (multiple == 0) return value;
    return static_cast<T>(std::ceil(static_cast<double>(value)/static_cast<double>(multiple))*static_cast<double>(multiple));
}

নীচে প্রদর্শিত হিসাবে "রাউন্ড ডাউন" বা আরও বেশি পরিচিত "বৃত্তাকার তল" টেম্পলেট ফাংশন হিসাবে তৈরি করুন:

template<typename T>
T roundFloorMultiple( T value, T multiple )
{
    if (multiple == 0) return value;
    return static_cast<T>(std::floor(static_cast<double>(value)/static_cast<double>(multiple))*static_cast<double>(multiple));
}

1
প্লাস 1, যদিও কিছু লোকেরা 0 টি ফিরে আসতে আরও স্বাচ্ছন্দ্য বোধ করতে পারে যখন
বহুবর্ণ

3
সাবধান, কারণ int64_t কে দ্বিগুণ রূপান্তর করা ক্ষয়ক্ষতিজনক হতে পারে, সুতরাং এটি টাইপ-জেনেরিকের মতো দেখা যায় না।
অ্যাড্রিয়ান ম্যাকার্থি

@ অ্যাড্রিয়ানম্যাকার্থি হ্যাঁ উপরের মতানুসারে আপনাকে সঠিক টেমপ্লেট বিশেষীকরণ তৈরি করতে হবে। আপনি দেখতে পাচ্ছেন, আমি long longএবং এর জন্য দুটি অতিরিক্ত ফাংশন বাস্তবায়ন করি long double। অন্য দুটি কার্যক্রমে স্পষ্টতই একই কাজটি করতে হবে।
ফ্লাভডিস

আমি মনে করি এটি এখন পর্যন্ত সকলের চেয়ে ধীর কিন্তু এটির দরকার হবে না। আপনাকে যা করতে হবে তা হল std :: सक्षम_if_t এবং পূর্ণসংখ্যা এবং ভাসমানদের জন্য দুটি শাখা করা। আপনি সংখ্যাযুক্ত_লিটগুলি আরও ভালভাবে ব্যবহার করতে পারেন এবং মান্টিসা আসলে মানটি ফিট করার জন্য যথেষ্ট বড় কিনা তা দেখতে পারেন। এটি সুরক্ষা যোগ করবে।
সোয়াইন

5

প্রথমত, আপনার ত্রুটির শর্তটির (একাধিক == 0) সম্ভবত কোনও ফেরতের মান থাকতে হবে। কি? আমি জানি না। সম্ভবত আপনি একটি ব্যতিক্রম ছুঁড়ে ফেলতে চান, এটি আপনার উপর নির্ভর করে। কিন্তু, কিছুই ফিরিয়ে দেওয়া বিপজ্জনক।

দ্বিতীয়ত, আপনার পরীক্ষা করা উচিত যে numToRound ইতিমধ্যে একাধিক নয়। অন্যথায়, আপনি যুক্ত multipleকরার সময় roundDown, আপনি ভুল উত্তর পাবেন।

তৃতীয়ত, আপনার কাস্টগুলি ভুল। আপনি numToRoundএকটি পূর্ণসংখ্যার কাছে কাস্ট করেছেন তবে এটি ইতিমধ্যে একটি পূর্ণসংখ্যা। বিভাগের পূর্বে দ্বিগুণ হওয়ার জন্য আপনাকে গুণন করতে হবে এবং গুণনের পরে ফিরে যেতে হবে।

সবশেষে, আপনি নেতিবাচক সংখ্যার জন্য কী চান? "আপ" রাউন্ডিংয়ের অর্থ শূন্যের গোলাকৃতির (ধনাত্মক সংখ্যার মতো একই দিকে গোলাকার) বা শূন্য থেকে দূরে (একটি "বৃহত্তর" নেতিবাচক সংখ্যা) হতে পারে। বা, সম্ভবত আপনি যত্ন নেই।

প্রথম তিনটি সমাধানের সাথে এখানে একটি সংস্করণ দেওয়া আছে, তবে আমি নেতিবাচক সমস্যাটি মোকাবেলা করি না:

int roundUp(int numToRound, int multiple)
{
 if(multiple == 0)
 {
  return 0;
 }
 else if(numToRound % multiple == 0)
 {
  return numToRound
 }

 int roundDown = (int) (( (double) numToRound / multiple ) * multiple);
 int roundUp = roundDown + multiple; 
 int roundCalc = roundUp;
 return (roundCalc);
}

@ পিটার এটা কি? আমি ধরে নিয়েছিলাম যে int / intএটি কোনও পূর্বাবস্থায় ফিরে আসবে, যা আমরা যা চাইছিলাম তা নয়।
মাইক ক্যারন

ইন্ট / ইন্টি আসলেই কোনও ইনট ফিরিয়ে দেয় তবে আপনি যা চান তা অবিকল এটি। উদাহরণস্বরূপ, numToRound = 7, একাধিক = 3. 7/3 = 2.
পিটার রুদারম্যান

4

রাউন্ড টু পাওয়ার দুই:

কেবলমাত্র যদি কারও জন্য দু'জনের পাওয়ারের নিকটতম একাধিককে গোলাকার ধনাত্মক সংখ্যার জন্য সমাধানের প্রয়োজন হয় (কারণ আমি এখানেই শেষ করেছি):

// number: the number to be rounded (ex: 5, 123, 98345, etc.)
// pow2:   the power to be rounded to (ex: to round to 16, use '4')
int roundPow2 (int number, int pow2) {
    pow2--;                     // because (2 exp x) == (1 << (x -1))
    pow2 = 0x01 << pow2;

    pow2--;                     // because for any
                                //
                                // (x = 2 exp x)
                                //
                                // subtracting one will
                                // yield a field of ones
                                // which we can use in a
                                // bitwise OR

    number--;                   // yield a similar field for
                                // bitwise OR
    number = number | pow2;
    number++;                   // restore value by adding one back

    return number;
}

যদি ইতোমধ্যে একাধিক হয় তবে ইনপুট নম্বরটি একই থাকবে।

এখানে, x86_64 আউটপুট জিসিসি সঙ্গে দেয় -O2বা -Os(9Sep2013 বিল্ড - অনলাইন godbolt জিসিসি):

roundPow2(int, int):
    lea ecx, [rsi-1]
    mov eax, 1
    sub edi, 1
    sal eax, cl
    sub eax, 1
    or  eax, edi
    add eax, 1
    ret

কোডের প্রতিটি সি লাইন সমাবেশে এর লাইনের সাথে পুরোপুরি মিলিত হয়: http://goo.gl/DZigfX

এই নির্দেশাবলী প্রত্যেকটি অত্যন্ত দ্রুত , তাই ফাংশন খুব দ্রুত। যেহেতু কোডটি খুব ছোট এবং দ্রুত, এটি inlineব্যবহার করার সময় এটি কার্যকরী হতে পারে ।


ক্রেডিট:


1
ঠিক আমি খুঁজছেন ছিল কি. ধন্যবাদ!
কিয়ো

1
int roundUpPow2 (int num, int Pow2) {রিটার্ন নাম্বার (Pow2 - 1) & ~ (Pow2 - 1); 30 প্রায় 30% দ্রুত এবং ব্যবহারে সহজ (আপনি 16 এর পরের
একাধিকটি

3

আমি ব্যাবহার করছি:

template <class _Ty>
inline _Ty n_Align_Up(_Ty n_x, _Ty n_alignment)
{
    assert(n_alignment > 0);
    //n_x += (n_x >= 0)? n_alignment - 1 : 1 - n_alignment; // causes to round away from zero (greatest absolute value)
    n_x += (n_x >= 0)? n_alignment - 1 : -1; // causes to round up (towards positive infinity)
    //n_x += (_Ty(-(n_x >= 0)) & n_alignment) - 1; // the same as above, avoids branch and integer multiplication
    //n_x += n_alignment - 1; // only works for positive numbers (fastest)
    return n_x - n_x % n_alignment; // rounds negative towards zero
}

এবং দুটি শক্তির জন্য:

template <class _Ty>
bool b_Is_POT(_Ty n_x)
{
    return !(n_x & (n_x - 1));
}

template <class _Ty>
inline _Ty n_Align_Up_POT(_Ty n_x, _Ty n_pot_alignment)
{
    assert(n_pot_alignment > 0);
    assert(b_Is_POT(n_pot_alignment)); // alignment must be power of two
    -- n_pot_alignment;
    return (n_x + n_pot_alignment) & ~n_pot_alignment; // rounds towards positive infinity (i.e. negative towards zero)
}

মনে রাখবেন যে উভয়টি রাউন্ডের নেতিবাচক মানগুলি শূন্যের দিকে (যার অর্থ সমস্ত মানের জন্য ধনাত্মক অনন্ত থেকে গোলাকার), উভয়ই স্বাক্ষরিত ওভারফ্লোতে (যা সি / সি ++ এ অপরিবর্তিত) এর উপর নির্ভর করে না।

এটি দেয়:

n_Align_Up(10, 100) = 100
n_Align_Up(110, 100) = 200
n_Align_Up(0, 100) = 0
n_Align_Up(-10, 100) = 0
n_Align_Up(-110, 100) = -100
n_Align_Up(-210, 100) = -200
n_Align_Up_POT(10, 128) = 128
n_Align_Up_POT(130, 128) = 256
n_Align_Up_POT(0, 128) = 0
n_Align_Up_POT(-10, 128) = 0
n_Align_Up_POT(-130, 128) = -128
n_Align_Up_POT(-260, 128) = -256

আমি n_Align_Up_POTযখন থেকে এটি ডেলফির টিলিস্ট ক্লাসের মধ্যে দেখেছি তখন থেকেই আপনার ব্যবহার করছি । এটির সীমাবদ্ধতা রয়েছে, যেমন সারিবদ্ধকরণ (একাধিক) 2 পাওয়ার হ'ল তবে এটি খুব কমই সমস্যা কারণ আমি বেশিরভাগই এটি এসএমআইডি-র সঠিক প্রান্তিককরণ পেতে / পরীক্ষা করতে ব্যবহার করি। এটি দুর্দান্ত and
ব্যবহারকারী 1593842

2

সম্ভবত ফ্লোটে কাস্ট করা এবং সিল () ব্যবহার করা সম্ভবত নিরাপদ - আপনি যদি না জানেন যে ইন্টি বিভাগটি সঠিক ফলাফল প্রদান করছে।


1
নোট করুন যে ডাবল কেবলমাত্র x86- ভিত্তিক মেশিনে 54 বিট অবদান রাখতে পারে। আপনার যদি 64৪-বিট ইনট থাকে তবে এটি শেষ পর্যন্ত ব্যর্থ হবে।
সোয়াইন

আইইইই 7575৪ স্ট্যান্ডার্ড ডাবল ছাড়া আর এক্স 64৪ সিপিএসের একটি 80 বিবিট অভ্যন্তরীণ ভাসমান পয়েন্ট থাকতে পারে তাই একক সংখ্যায় অপারেশন নির্ভরযোগ্য
মার্টিন বেকেট

1
যদিও এটি সত্য, আপনার C / C ++ থেকে এই রাউন্ডিংয়ের উপর খুব কম নিয়ন্ত্রণ রয়েছে। এটি নিয়ন্ত্রণ শব্দ সেটিংসের উপর নির্ভর করে এবং এটি 80 বিটেরও কম গোলাকার হতে পারে। এছাড়াও আপনার এসএসই এবং অন্যান্য সিমডি নির্দেশিকা সেট রয়েছে যার কোনও বাড়ানো মধ্যবর্তী নেই (ভেক্টরাইজিং সংকলক এগুলি সহজেই ব্যবহার করতে পারে)।
সোয়াইন

2
int noOfMultiples = int((numToRound / multiple)+0.5);
return noOfMultiples*multiple

সি ++ প্রতিটি সংখ্যা নীচে নেমে আসে, সুতরাং আপনি যদি 0.5 যোগ করেন (এটির 1.5 এটি 2 হবে) তবে 1.49 তাই 1.99 হবে।

সম্পাদনা - দুঃখিত আপনি দেখতে চান নি, আমি +0.5 এর পরিবর্তে সিল () পদ্ধতিটি ব্যবহার করার পরামর্শ দেব


2

একটি জিনিস জন্য ভাল, যেহেতু আমি সত্যিই বুঝতে পারি না আপনি কি করতে চান, লাইন

int roundUp = roundDown + multiple;
int roundCalc = roundUp;
return (roundCalc); 

অবশ্যই সংক্ষিপ্ত করা যেতে পারে

int roundUp = roundDown + multiple;
return roundUp;

2

এই সাহায্য করতে পারেন হতে পারে:

int RoundUpToNearestMultOfNumber(int val, int num)
{
  assert(0 != num);
  return (floor((val + num) / num) * num);
}

মেঝে এবং পূর্ণসংখ্যা বিভাগ কেন ব্যবহার করবেন? মেঝেতে কিছুই নেই। যদি এটি দ্বিগুণ হয় তবে আপনি কমপক্ষে নেতিবাচক মানগুলির হ্যান্ডলিংয়ের উত্তরাধিকারী হতে পারেন।
সোয়াইন

2

সর্বদা গোল করা

int alwaysRoundUp(int n, int multiple)
{
    if (n % multiple != 0) {
        n = ((n + multiple) / multiple) * multiple;

        // Another way
        //n = n - n % multiple + multiple;
    }

    return n;
}

সর্বদা রাউন্ডআপ (1, 10) -> 10

সর্বদা রাউন্ডআপ (5, 10) -> 10

সর্বদা রাউন্ডআপ (10, 10) -> 10


সর্বদা নিচে গোল করা

int alwaysRoundDown(int n, int multiple)
{
    n = (n / multiple) * multiple;

    return n;
}

সর্বদা রাউন্ডডাউন (1, 10) -> 0

সর্বদা রাউন্ডডাউন (5, 10) -> 0

সর্বদা রাউন্ডডাউন (10, 10) -> 10


সাধারণ পথে গোল করা

int normalRound(int n, int multiple)
{
    n = ((n + multiple/2)/multiple) * multiple;

    return n;
}

নরমাল রাউন্ড (1, 10) -> 0

নরমাল রাউন্ড (5, 10) -> 10

নরমাল রাউন্ড (10, 10) -> 10


2

2 এর পাওয়ার হতে পারে এমন নিকটতম একাধিকের বৃত্তাকার

unsigned int round(unsigned int value, unsigned int multiple){
    return ((value-1u) & ~(multiple-1u)) + multiple;
}

ক্যাচেলিনগুলি বন্টন করার সময় এটি কার্যকর হতে পারে, যেখানে আপনি চান গোলাকার বর্ধন দুইটি শক্তি, তবে ফলস্বরূপ মানটি এর একাধিক হওয়া প্রয়োজন। উপর gccএই ফাংশন শরীরের কোন বিভাগ বা শাখার সঙ্গে 8 সমাবেশ নির্দেশাবলী তৈরি করে।

round(  0,  16) ->   0
round(  1,  16) ->  16
round( 16,  16) ->  16
round(257, 128) -> 384 (128 * 3)
round(333,   2) -> 334

1

আমি একটি অ্যালগরিদম পেয়েছি যা উপরের পোস্টের মতো কিছুটা অনুরূপ:

int [(| x | + n-1) / n] * [(nx) / | x |], যেখানে x হল একটি ব্যবহারকারী-ইনপুট মান এবং এন একাধিক ব্যবহৃত হচ্ছে।

এটি সমস্ত মান x এর জন্য কাজ করে, যেখানে x একটি পূর্ণসংখ্যা (শূন্য সহ ধনাত্মক বা negativeণাত্মক)। আমি এটি বিশেষত সি ++ প্রোগ্রামের জন্য লিখেছি, তবে এটি মূলত যে কোনও ভাষায় প্রয়োগ করা যেতে পারে।


1

নেতিবাচক numToRound জন্য:

এটি করা সত্যিই সহজ হওয়া উচিত তবে স্ট্যান্ডার্ড মডুলো% অপারেটর যেমন প্রত্যাশা করতে পারে তেমন নেতিবাচক সংখ্যাগুলি পরিচালনা করে না। উদাহরণস্বরূপ -14% 12 = -2 এবং 10 নয়। প্রথমে কাজটি হল মডুলো অপারেটর পাওয়া যা কখনই নেতিবাচক সংখ্যা ফেরায় না। তাহলে রাউন্ডআপ সত্যিই সহজ।

public static int mod(int x, int n) 
{
    return ((x % n) + n) % n;
}

public static int roundUp(int numToRound, int multiple) 
{
    return numRound + mod(-numToRound, multiple);
}

1

এটি আমি করতাম:

#include <cmath>

int roundUp(int numToRound, int multiple)
{
    // if our number is zero, return immediately
   if (numToRound == 0)
        return multiple;

    // if multiplier is zero, return immediately
    if (multiple == 0)
        return numToRound;

    // how many times are number greater than multiple
    float rounds = static_cast<float>(numToRound) / static_cast<float>(multiple);

    // determine, whether if number is multiplier of multiple
    int floorRounds = static_cast<int>(floor(rounds));

    if (rounds - floorRounds > 0)
        // multiple is not multiplier of number -> advance to the next multiplier
        return (floorRounds+1) * multiple;
    else
        // multiple is multiplier of number -> return actual multiplier
        return (floorRounds) * multiple;
}

কোডটি সর্বোত্তম নাও হতে পারে তবে আমি শুকনো পারফরম্যান্সের চেয়ে ক্লিন কোড পছন্দ করি।


কাস্টিং intকরতে floatনির্দ্ধিধায় স্পষ্টতা হারায় এবং ভুল উত্তরের করে তোলে।
chux -

1
int roundUp (int numToRound, int multiple)
{
  return multiple * ((numToRound + multiple - 1) / multiple);
}

যদিও:

  • নেতিবাচক সংখ্যার জন্য কাজ করবে না
  • numRound + একাধিক ওভারফ্লো হলে কাজ করবে না

পরিবর্তে স্বাক্ষরবিহীন পূর্ণসংখ্যা ব্যবহার করার পরামর্শ দিবে, যা ওভারফ্লো আচরণের সংজ্ঞা দিয়েছে।

আপনি একাধিক == 0 ব্যতিক্রম পাবেন তবে এ ক্ষেত্রে যাইহোক এটি কোনও সুস্পষ্ট সংজ্ঞাযুক্ত সমস্যা নয়।


1

C:

int roundUp(int numToRound, int multiple)
{
  return (multiple ? (((numToRound+multiple-1) / multiple) * multiple) : numToRound);
}

এবং আপনার ~ / .Bashrc এর জন্য:

roundup()
{
  echo $(( ${2} ? ((${1}+${2}-1)/${2})*${2} : ${1} ))
}

1

আমি xইতিমধ্যে একাধিক হলে অবশিষ্টের যোগটি বাতিল করতে মডুলাসের সংমিশ্রণটি ব্যবহার করি :

int round_up(int x, int div)
{
    return x + (div - x % div) % div;
}

আমরা যে ভাজক দিয়ে আবার এটা খর্ব হলে এটা ভাজক নিজেই তারপর যোগ হয় বাকি বিপরীত খুঁজে তারপর মডুলাস x

round_up(19, 3) = 21

1

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

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

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

int RoundUp(int n, int multiple)
{
    // prevent divide by 0 by returning n
    if (multiple == 0) return n;

    // calculate the rounded down version
    int roundedDown = n / multiple * multiple;

    // if the rounded version and original are the same, then return the original
    if (roundedDown == n) return n;

    // handle negative number and round up according to the sign
    // NOTE: if n is < 0 then subtract the multiple, otherwise add it
    return (n < 0) ? roundedDown - multiple : roundedDown + multiple;
}

সঙ্গে ব্যর্থ RoundUp(INT_MIN, -1)যেমন n / multipleহয় intওভারফ্লো।
chux -

1

আমি মনে করি এটি আপনার সাহায্য করা উচিত। সি তে নীচের প্রোগ্রামটি লিখেছি।

# include <stdio.h>
int main()
{
  int i, j;
  printf("\nEnter Two Integers i and j...");
  scanf("%d %d", &i, &j);
  int Round_Off=i+j-i%j;
  printf("The Rounded Off Integer Is...%d\n", Round_Off);
  return 0;
}

0
/// Rounding up 'n' to the nearest multiple of number 'b'.
/// - Not tested for negative numbers.
/// \see http://stackoverflow.com/questions/3407012/
#define roundUp(n,b) ( (b)==0 ? (n) : ( ((n)+(b)-1) - (((n)-1)%(b)) ) )

/// \c test->roundUp().
void test_roundUp() {   
    // yes_roundUp(n,b) ( (b)==0 ? (n) : ( (n)%(b)==0 ? n : (n)+(b)-(n)%(b) ) )
    // yes_roundUp(n,b) ( (b)==0 ? (n) : ( ((n + b - 1) / b) * b ) )

    // no_roundUp(n,b) ( (n)%(b)==0 ? n : (b)*( (n)/(b) )+(b) )
    // no_roundUp(n,b) ( (n)+(b) - (n)%(b) )

if (true) // couldn't make it work without (?:)
{{  // test::roundUp()
    unsigned m;
                { m = roundUp(17,8); } ++m;
    assertTrue( 24 == roundUp(17,8) );
                { m = roundUp(24,8); }
    assertTrue( 24 == roundUp(24,8) );

    assertTrue( 24 == roundUp(24,4) );
    assertTrue( 24 == roundUp(23,4) );
                { m = roundUp(23,4); }
    assertTrue( 24 == roundUp(21,4) );

    assertTrue( 20 == roundUp(20,4) );
    assertTrue( 20 == roundUp(19,4) );
    assertTrue( 20 == roundUp(18,4) );
    assertTrue( 20 == roundUp(17,4) );

    assertTrue( 17 == roundUp(17,0) );
    assertTrue( 20 == roundUp(20,0) );
}}
}

0

এটি ইতিবাচক পূর্ণসংখ্যার জন্য আপনি যে ফলাফলগুলি সন্ধান করছেন তা পাচ্ছে:

#include <iostream>
using namespace std;

int roundUp(int numToRound, int multiple);

int main() {
    cout << "answer is: " << roundUp(7, 100) << endl;
    cout << "answer is: " << roundUp(117, 100) << endl;
    cout << "answer is: " << roundUp(477, 100) << endl;
    cout << "answer is: " << roundUp(1077, 100) << endl;
    cout << "answer is: " << roundUp(52,20) << endl;
    cout << "answer is: " << roundUp(74,30) << endl;
    return 0;
}

int roundUp(int numToRound, int multiple) {
    if (multiple == 0) {
        return 0;
    }
    int result = (int) (numToRound / multiple) * multiple;
    if (numToRound % multiple) {
        result += multiple;
    } 
    return result;
}

এবং ফলাফলগুলি এখানে:

answer is: 100
answer is: 200
answer is: 500
answer is: 1100
answer is: 60
answer is: 90

0

আমি মনে করি এটি কাজ করে:

int roundUp(int numToRound, int multiple) {
    return multiple? !(numToRound%multiple)? numToRound : ((numToRound/multiple)+1)*multiple: numToRound;
}

-1

এটি আমার পক্ষে কাজ করে তবে নেতিবাচক বিষয়গুলি পরিচালনা করার চেষ্টা করেনি

public static int roundUp(int numToRound, int multiple) {
    if (multiple == 0) {
        return 0;
    } else if (numToRound % multiple == 0) {
    return numToRound;
    }

    int mod = numToRound % multiple;
    int diff = multiple - mod;
    return numToRound + diff;
}

-2

কমনীয়তার ধারণাটি দেখানোর জন্য এখানে একটি দুর্দান্ত সহজ সমাধান। এটি মূলত গ্রিড স্ন্যাপগুলির জন্য।

(সুডোকোড)

nearestPos = Math.Ceil( numberToRound / multiple ) * multiple;

আপনি কি আপনার ধারণা জমা দেওয়ার বিষয়টি পরীক্ষা করেছেন? এটি স্রষ্টার উত্তর দেয় না
ইয়াওদব

এটি এমনকি বৈধ কোড নয়।
ব্যবহারকারী 13783520
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.