পূর্ণসংখ্যা বিভাগের ফলাফল কীভাবে গোল করবেন?


335

আমি যখন সি # বা জাভা এর মতো কোনও ভাষা ব্যবহার করি তখন কীভাবে পৃষ্ঠাবদ্ধকরণ নিয়ন্ত্রণগুলি প্রদর্শন করব সে সম্পর্কে বিশেষভাবে ভাবছি।

যদি আমার কাছে এক্স আইটেম থাকে যা আমি প্রতি পৃষ্ঠার y এর অংশগুলিতে প্রদর্শন করতে চাই তবে কত পৃষ্ঠার প্রয়োজন হবে?


1
আমি কিছু অনুপস্থিত করছি? y / x + 1 দুর্দান্ত কাজ করে (আপনি যদি জানেন / অপারেটরটি সর্বদা রাউন্ড ডাউন হয়)।
rikkit

51
@্রিককিট - যদি y এবং x সমান হয় তবে y / x + 1 এর চেয়ে অনেক বেশি।
ইয়ান নেলসন

1
এখনই এটির সন্ধানকারী যে কোনও ব্যক্তির জন্য, দ্বাপের প্রশ্নের এই উত্তরটি দ্বিগুণ হওয়া অপ্রয়োজনীয় রূপান্তর এড়ানো এবং একটি স্পষ্ট ব্যাখ্যা প্রদানের পাশাপাশি অতিরিক্ত প্রবাহ উদ্বেগকে এড়িয়ে চলে।
জেডএক্স 9

2
@IanNelson আরো সাধারণভাবে যদি xদিয়ে বিভাজ্য y, y/x + 1এক খুব বেশী হবে।
ওহাদ স্নাইডার

1
@ জেডএক্স 9 না, এটি ওভারফ্লো উদ্বেগ এড়ানো যায় না। ইয়ান নেলসন এখানে পোস্ট করেছেন ঠিক এটি একই সমাধান।
ব্যবহারকারী 247702

উত্তর:


478

একটি মার্জিত সমাধান পেয়েছে:

int pageCount = (records + recordsPerPage - 1) / recordsPerPage;

উত্স: নম্বর রূপান্তর, রোল্যান্ড ব্যাকহাউস, 2001



30
মিঃ ওবুইশ বলেছেন: রেকর্ডপিরপেজটি শূন্য নয় তা নিশ্চিত করতে ভুলবেন না
অ্যাডাম জেন্ট

7
ভাল কাজ, আমি বিশ্বাস করতে পারি না সি # এর পূর্ণসংখ্যার সিলিং নেই।
gosukiwi

2
হ্যাঁ, আমি আরও অনেক জটিল পদ্ধতির চেষ্টা করার পরে আমি 2017 সালের মাঝামাঝি এই দুর্দান্ত উত্তরে হোঁচট খাচ্ছি।
মিফো

1
পাইথনের মতো উপযুক্ত ইউক্লিডিয়ান-বিভাগ অপারেটরের ভাষাগুলির জন্য আরও সহজ পদ্ধতির উপায় হবে pageCount = -((-records) // recordsPerPage)
সুপারক্যাট

194

ফ্লোটিং পয়েন্টে এবং পিছনে রূপান্তর করা সিপিইউ স্তরে সময় নষ্ট করার মতো মনে হয়।

আয়ান নেলসনের সমাধান:

int pageCount = (records + recordsPerPage - 1) / recordsPerPage;

সরলীকৃত করা যেতে পারে:

int pageCount = (records - 1) / recordsPerPage + 1;

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

অর্থাৎ এটি অকার্যকর হতে পারে, যদি config.fetch_value কোনও ডাটাবেস অনুসন্ধান বা কিছু ব্যবহার করে:

int pageCount = (records + config.fetch_value('records per page') - 1) / config.fetch_value('records per page');

এটি এমন একটি পরিবর্তনশীল তৈরি করে যা আপনার সত্যই প্রয়োজন হয় না, যা সম্ভবত (গৌণ) স্মৃতিশক্তিযুক্ত থাকে এবং এটি খুব বেশি টাইপ করে:

int recordsPerPage = config.fetch_value('records per page')
int pageCount = (records + recordsPerPage - 1) / recordsPerPage;

এটি সমস্তই এক লাইন, এবং কেবল একবার ডেটা এনে দেয়:

int pageCount = (records - 1) / config.fetch_value('records per page') + 1;

5
+1, শূন্য রেকর্ডগুলির ইস্যুটি এখনও 1 পৃষ্ঠার অ্যাকাউন্ট ফেরত দেওয়ার বিষয়টি আসলে সহজ, যেহেতু আমি এখনও 1 পৃষ্ঠা চাইব, "কোনও রেকর্ড আপনার মানদণ্ডের সাথে মেলে না" এর স্থানধারক / জাল সারি দেখায়, কোনও "0 পৃষ্ঠা গণনা" ইস্যু এড়াতে সহায়তা করে পৃষ্ঠাগুলি নিয়ন্ত্রণ আপনি ব্যবহার।
টিমোথি ওয়াল্টার্স

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

10
লোকেরা এটি স্ক্যান করে এবং বোডমাস মিস করার জন্য স্পষ্টতার জন্য ছোট সম্পাদনা যখন নেলসন সমাধান থেকে সরলকরণে পরিবর্তন করার সময় (যেমন আমি প্রথমবার! + 1;
ডেভ হেউড

1
সরলীকৃত সংস্করণে আপনার প্রথম বন্ধনী যুক্ত করা উচিত যাতে এটি নির্দিষ্ট ক্রিয়াকলাপের উপর নির্ভর করে না। যেমন, ((রেকর্ডস - 1) / রেকর্ডস পেজ) + 1.
মার্টিন

1
@Ian, এই উত্তর সবসময় 1. ফেরত দেয় না এটা 0 ফিরে আসতে পারেন যদি আপনার recordsPerPage "1" এবং সেখানে 0 রেকর্ড আছেন: -1 / 1 + 1 = 0। যদিও এটি কোনও অতি সাধারণ ঘটনা নয়, আপনি যদি ব্যবহারকারীদের পৃষ্ঠার আকার সামঞ্জস্য করতে দিচ্ছেন তবে তা মনে রাখা গুরুত্বপূর্ণ। সুতরাং হয় ব্যবহারকারীদের পৃষ্ঠার আকার 1 এর মঞ্জুরি না দেয়, পৃষ্ঠার আকারের উপর পরীক্ষা করুন বা উভয়ই (সম্ভবত অপ্রত্যাশিত আচরণ এড়াতে পছন্দনীয়)।
মাইকেল 23

81

সি # এর জন্য সমাধানটি হ'ল মানগুলিকে দ্বিগুণ করা হয় (যেমন ম্যাথ। সিইলিং একটি ডাবল লাগে):

int nPages = (int)Math.Ceiling((double)nItems / (double)nItemsPerPage);

জাভাতে আপনার ম্যাথ.সিল () দিয়ে একই কাজ করা উচিত।


4
এই উত্তরটি কেন এতটা নিচে নেমেছে যখন অপশনটি সি # তে স্পষ্টভাবে জিজ্ঞাসা করছে!
felickz

2
আপনাকে আউটপুটও কাস্ট করতে হবে intকারণ ইনপুট ধরণের উপর নির্ভর করে Math.Ceilingএকটি doubleবা প্রদান decimalকরে।
ড্যানএম 7

15
কারণ এটি অত্যন্ত অদক্ষ
জার শারদান

6
এটি অদক্ষ হতে পারে তবে এটি বোঝা অত্যন্ত সহজ। প্রদত্ত পৃষ্ঠার গণনা গণনা করা হয় সাধারণত অনুরোধের পরে একবার করা হয় কোনও কার্যকারিতা ক্ষতি মাপার যোগ্য নয়।
জ্যারেড কেলস

1
এটি "(ডিভিডেন্ড + (বিভাজক - 1)) / বিভাজকের তুলনায় সবেমাত্র পঠনযোগ্য;" এছাড়াও এটি ধীর এবং গণিত লাইব্রেরি প্রয়োজন।
রোল করে

68

এটি আপনার যা চান তা আপনাকে দেওয়া উচিত। আপনি অবশ্যই প্রতি পৃষ্ঠায় y আইটেম দ্বারা বিভক্ত x আইটেমগুলি দেখতে চাইবেন, যখন অসম সংখ্যা উপস্থিত হয় তখন সমস্যা হয়, তাই যদি কোনও আংশিক পৃষ্ঠা থাকে তবে আমরা একটি পৃষ্ঠা যুক্ত করতে চাই।

int x = number_of_items;
int y = items_per_page;

// with out library
int pages = x/y + (x % y > 0 ? 1 : 0)

// with library
int pages = (int)Math.Ceiling((double)x / (double)y);

5
x / y + !! (x% y) সি-জাতীয় ভাষার শাখা এড়িয়ে চলে। বিভেদগুলি ভাল, তবে আপনার সংকলক যেভাবেই তা করছে।
Rhys Ulerich

2
উপরের উত্তরের মতো উপচে না পড়ার জন্য +1 ... যদিও ম্যাথ.সিলিংয়ের জন্য ইনটকে ডাবলসে রূপান্তর করা হয়েছে এবং তারপরে আবার ফিরে আসা পারফরম্যান্স সংবেদনশীল কোডের একটি খারাপ ধারণা।
কোগওয়েল

3
@RhysUlerich যা সি # তে কাজ করে না (সরাসরি কোনও ইনটকে একটি বুলে রূপান্তর করতে পারে না)। আমার মনে হয় শাখা প্রশাখি এড়ানোর একমাত্র উপায় হ'ল rjmunro এর সমাধান।
smead

18

ইয়ান প্রদত্ত পূর্ণসংখ্যার গণিত সমাধানটি দুর্দান্ত তবে পূর্ণসংখ্যার ওভারফ্লো বাগ থেকে ভুগছে। ভেরিয়েবলগুলি সবই ধরে নিলে intসমাধানটি longগণিতটি ব্যবহার করতে এবং বাগটি এড়াতে পুনরায় লেখা যেতে পারে :

int pageCount = (-1L + records + recordsPerPage) / recordsPerPage;

যদি recordsএটি হয় longতবে বাগটি রয়ে গেছে। মডুলাস দ্রবণটিতে বাগ নেই।


4
আমি মনে করি না আপনি উপস্থাপিত দৃশ্যে আপনি বাস্তবে এই বাগটি আঘাত করতে চলেছেন। 2 ^ 31 রেকর্ডগুলি পেজটিতে থাকার জন্য যথেষ্ট।
rjmunro


@ ফিনিউ: এএফআইএক্স, সেই পৃষ্ঠায় সত্যিকারের বিশ্বের উদাহরণ নেই, তাত্ত্বিক দৃশ্যে ত্রুটি খুঁজে পাওয়া অন্য কারও রিপোর্ট।
rjmunro

5
হ্যাঁ, আমি বাগটি নির্দেশ করার জন্য পেডেন্টিক ছিলাম। কখনও কখনও কোনও সমস্যা তৈরি না করেই অনেকগুলি বাগ চিরস্থায়ীভাবে থাকতে পারে। জেডিকে বাইনারি অনুসন্ধান প্রয়োগে একই ফর্মের একটি বাগ কিছু নয় বছর ধরে বিদ্যমান ছিল, কেউ এটি রিপোর্ট করার আগে ( googleresearch.blogspot.com/2006/06/… )। আমি অনুমান করি যে প্রশ্নটি আপনি যতই সম্ভাব্য হোন না কেন এই বাগটি মোকাবিলা করার সম্ভাবনা নেই, কেন সামনের দিকে ঠিক করবেন না?
ব্র্যান্ডন ডুরেট

4
এছাড়াও, এটি লক্ষ করা উচিত যে এটি কেবলমাত্র বিষয়গুলির মধ্যে পৃষ্ঠাযুক্ত উপাদানগুলির সংখ্যা নয়, এটি পৃষ্ঠার আকারও। সুতরাং, যদি আপনি একটি লাইব্রেরি তৈরি করে থাকেন এবং কেউ পৃষ্ঠার আকার হিসাবে 2 ^ 31-1 (পূর্ণসংখ্যা.এমএক্স_ভ্যালু) পাস না করে পৃষ্ঠাটি না বেছে নিচ্ছেন, তবে বাগটি ট্রিগার করা হবে।
ব্র্যান্ডন ডুরেট

7

নিক বেরার্ডির উত্তরের একটি বৈকল্পিক যা একটি শাখা এড়ায়:

int q = records / recordsPerPage, r = records % recordsPerPage;
int pageCount = q - (-r >> (Integer.SIZE - 1));

দ্রষ্টব্য: (-r >> (Integer.SIZE - 1))সাইন বিট নিয়ে r32 বার পুনরাবৃত্তি হয়েছে ( >>অপারেটরের এক্সটেনশন সাইন ইন ধন্যবাদ ।) এটি rশুন্য বা নেতিবাচক হলে 0-এ মূল্যায়ন করে , rইতিবাচক হলে -1 হয়। সুতরাং এটি থেকে বিয়োগ করলে q1 যুক্ত করার প্রভাব রয়েছে records % recordsPerPage > 0


4

রেকর্ডস জন্য == 0, rjmunro এর সমাধানটি 1 দেয় 1 সঠিক সমাধানটি 0 এটি বলেছিল, আপনি যদি জানেন যে রেকর্ডগুলি> 0 (এবং আমি নিশ্চিত যে আমরা সমস্ত রেকর্ডস পেয়ারপেজ> 0) ধরে রেখেছি, তবে rjmunro সমাধান সঠিক ফলাফল দেয় এবং ওভারফ্লো সমস্যাগুলির কোনও নেই।

int pageCount = 0;
if (records > 0)
{
    pageCount = (((records - 1) / recordsPerPage) + 1);
}
// no else required

সমস্ত পূর্ণসংখ্যার গণিতের সমাধানগুলি যে কোনও ভাসমান পয়েন্ট সমাধানের চেয়ে কার্যকর হতে চলেছে ।


এই পদ্ধতিটি কোনও পারফরম্যান্স বাধা হওয়ার সম্ভাবনা নেই। এবং যদি এটি হয় তবে আপনার শাখার দামও বিবেচনা করা উচিত।
ফিনউইউ

4

একটি এক্সটেনশন পদ্ধতির প্রয়োজন:

    public static int DivideUp(this int dividend, int divisor)
    {
        return (dividend + (divisor - 1)) / divisor;
    }

এখানে কোনও চেক নেই (ওভারফ্লো, DivideByZeroইত্যাদি), যদি আপনি চান তবে যোগ করতে নির্দ্বিধায়। যাইহোক, পদ্ধতি আহ্বান ওভারহেড সম্পর্কে উদ্বিগ্নদের জন্য, এর মতো সাধারণ ফাংশনগুলি যেভাবেই হোক সংকলক দ্বারা ইনডিল করা যেতে পারে, তাই আমি মনে করি না যে এটি যেখানে উদ্বিগ্ন হবে। চিয়ার্স।

পিএস আপনি এটি সম্পর্কে সচেতন হতে দরকারী হতে পারে (এটি বাকি থাকে):

    int remainder; 
    int result = Math.DivRem(dividend, divisor, out remainder);

1
এটি ভুল। উদাহরণস্বরূপ: DivideUp(4, -2)0 প্রদান করে (-২ হওয়া উচিত)। এটি কেবল অ-নেতিবাচক পূর্ণসংখ্যার জন্যই সঠিক যা উত্তর থেকে বা ফাংশনের ইন্টারফেস থেকে পরিষ্কার নয়।
থাকস

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

1
উল্লিখিত প্রশ্নটিতে "আমি কীভাবে পৃষ্ঠাগুলি নিয়ন্ত্রণগুলি প্রদর্শন করব সে সম্পর্কে বিশেষভাবে ভাবছি " তাই নেতিবাচক সংখ্যা যেভাবেই সীমা ছাড়িয়ে যেত। আবার, কেবল দরকারী কিছু করুন এবং যদি আপনি চান তবে একটি অতিরিক্ত চেকের পরামর্শ দিন, এটি একটি দলের প্রচেষ্টা ব্যক্তি।
নিকোলাস পিটারসেন

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

2

অন্য বিকল্পটি হল মোড () ফাংশন (বা '%') ব্যবহার করা। যদি একটি শূন্য-অবশিষ্ট অবশিষ্ট থাকে তবে বিভাগের পূর্ণসংখ্যার ফলাফল বৃদ্ধি করুন।


1

আমি নিম্নলিখিতটি করি, যে কোনও ওভারফ্লোগুলি পরিচালনা করি:

var totalPages = totalResults.IsDivisble(recordsperpage) ? totalResults/(recordsperpage) : totalResults/(recordsperpage) + 1;

এবং 0 টি ফলাফলের জন্য এই এক্সটেনশনটি ব্যবহার করুন:

public static bool IsDivisble(this int x, int n)
{
           return (x%n) == 0;
}

এছাড়াও, বর্তমান পৃষ্ঠা নম্বরটির জন্য (জিজ্ঞাসা করা হয়নি তবে দরকারী হতে পারে):

var currentPage = (int) Math.Ceiling(recordsperpage/(double) recordsperpage) + 1;

0

শূন্যের জন্য পরীক্ষায় ব্রাঞ্চিং সরানোর বিকল্প:

int pageCount = (records + recordsPerPage - 1) / recordsPerPage * (records != 0);

এটি সি # তে কাজ করবে কিনা তা নিশ্চিত নন, সি / সি ++ এ করা উচিত।


-1

একটি জেনেরিক পদ্ধতি, যার ফলস্বরূপ আপনি পুনরাবৃত্তি করতে পারবেন আগ্রহী হতে পারে:

public static Object[][] chunk(Object[] src, int chunkSize) {

    int overflow = src.length%chunkSize;
    int numChunks = (src.length/chunkSize) + (overflow>0?1:0);
    Object[][] dest = new Object[numChunks][];      
    for (int i=0; i<numChunks; i++) {
        dest[i] = new Object[ (i<numChunks-1 || overflow==0) ? chunkSize : overflow ];
        System.arraycopy(src, i*chunkSize, dest[i], 0, dest[i].length); 
    }
    return dest;
}

পেয়ারা একটি অনুরূপ পদ্ধতি ( Lists.partition(List, int)) এবং উদ্বেগজনকভাবেsize() ফলাফলের পদ্ধতি Listহিসাবে (হিসাবে r09) ব্র্যান্ডন ডুরেটের উত্তরে উল্লিখিত ওভারফ্লো বাগটি ভোগ করে ।
ফিনউইউ

-2

আমার অনুরূপ প্রয়োজন ছিল যেখানে আমার মিনিটগুলি ঘন্টা এবং মিনিটে রূপান্তর করতে হবে। আমি যা ব্যবহার করেছি তা হ'ল:

int hrs = 0; int mins = 0;

float tm = totalmins;

if ( tm > 60 ) ( hrs = (int) (tm / 60);

mins = (int) (tm - (hrs * 60));

System.out.println("Total time in Hours & Minutes = " + hrs + ":" + mins);

-2

উপরের সমাধানগুলির চেয়ে নীচে আরও গোল করা উচিত, তবে কার্য সম্পাদনের ব্যয়ে (0.5 * আরসিটিডিনোমিনেটরের ভাসমান পয়েন্ট গণনার কারণে):

uint64_t integerDivide( const uint64_t& rctNumerator, const uint64_t& rctDenominator )
{
  // Ensure .5 upwards is rounded up (otherwise integer division just truncates - ie gives no remainder)
  return (rctDenominator == 0) ? 0 : (rctNumerator + (int)(0.5*rctDenominator)) / rctDenominator;
}

-4

আপনি ভাসমান পয়েন্ট বিভাগ করতে চান এবং তারপরে সিলিং ফাংশনটি ব্যবহার করে পরবর্তী পূর্ণসংখ্যার মানটি নির্ধারণ করতে পারেন।

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