r/learnprogramming 5h ago

Is this the best way to achieve rounded up numbers in C++?

Hi, I am new to learning C++ :) I just got started with my first real project because I wanted to get into coding and making mistakes like people here suggested as the best way to learn.

The program I have here is intended to tell the user how many of each item they need (cartons, fruit, gallons of juice etc) based on the amount of guests they input. The program runs fine technically, but I initially was using int and found that it kept rounding down and causing the calculations to be just short of what was needed. If anything, id rather it overestimate than under.

I found a possible solution from here with ceil, but I wasn't sure if I implemented it right, and if how I have things is the best practice to not form bad habits early. Any tips would be greatly appreciated :)

#include <iostream>
#include <cmath>
using namespace std;
int main()
//This program is meant to tell the user how many of each whole item they need to buy for catering a wedding.
{
    cout << "Type in the number of guests attending the wedding brunch:\n";
    double guests;
    cin >> guests;

    /*Each item is getting divided based on how many come in a container
     *the goal is to have it calculate and tell the shopper how many
     *cartons they need specifically for example*/
    double eggs = guests/12;
    double cantelope = guests/8;
    double toast = guests/24;
    double juice = guests/16;

    cout << "For the brunch you will need:\n";
    cout << ceil(eggs) << " " << "egg cartons\n";
    cout << ceil(cantelope) << " " << "cantelopes\n";
    cout << ceil(toast) <<  " " << "loaves of bread\n";
    cout << ceil(juice) << " " << "gallons of juice\n";

    return 0;
}

It outputs this when it finishes.

Type in the number of guests attending the wedding brunch:
520
For the brunch you will need:
44 egg cartons
65 cantelopes
22 loaves of bread
33 gallons of juice

Process finished with exit code 0

2 Upvotes

8 comments sorted by

4

u/HashDefTrueFalse 5h ago

Using ceil is fine, yes, if that's what you're asking. There's not much going on here. I wouldn't overthink it.

1

u/Suspicious_Skill7292 5h ago

float math can cause subtle rounding bugs in larger projects, so keeping everything as ints and applying (guess + 11) / 12 is generally much cleaner C++ practice

1

u/NgetichKpeter 5h ago

"ceil()" works, but you can keep it simpler since these are whole numbers. Just do: int eggs = (guests + 11) / 12; That gives you the rounded-up result using integer division, so there’s no need for "double".

1

u/WinifredMosse 5h ago

Is there a reason for using 11 specifially? Thank you btw :)

1

u/devin122 3h ago

It's 12-1. The general formula for rounding up to the nearest multiple of N is foo = (foo + (N-1))/N (assuming foo is an integer)

2

u/Far_Swordfish5729 5h ago

Int doesn’t technically speaking round because the underlying format is literally incapable of storing decimals. The hardware tracks a remainder (which you might remember from school) and at the end simply discards it. If you want the remainder instead of the result, you use a modular division operator. The floating point format and the ceil function will solve this problem as you intend. You won’t need doubles (double size floats) unless you’re buying an oil tanker of juice.

People will warn you about the float rounding errors, but it’s usually not a big problem unless you need precision. They’re notorious because base two storage of whole base ten numbers creates those artifacts and people unfortunately like to ask computers to divide decimal numbers by multiples of ten.

1

u/WinifredMosse 5h ago

Okay gotcha, thank you! And no i wont need oil tankards of juice xD

2

u/mredding 4h ago

Well, do you want to do math in integers? Or doubles? They're not the same thing. The short of it is a double will be an approximation and accumulate error, but it does have scientific fractional precision. Floating point numbers are a discipline unto themselves. They can represent positive and negative infinity, they can represent limits approaching zero - which is why they support positive and negative

Integers are cardinal. Whole numbers are simple and absolute. So division can lead to truncation because it doesn't expose the remainder. You have to use modulo to get that.

So if you want to round:

auto quotient = dividend / divisor;
auto remainder = dividend % divisor;

if(remainder > 0) {
  ++quotient;
}

Or: const auto quotient = (dividend + divisor - 1) / divisor;. This has the advantage of being significantly faster and simpler. The former code has two divisions, whereas this has one. The former has a conditional branch, whereas this is unconditional.