C
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Functions
-
Section 4: Arrays and Strings
-
Section 5: Pointers
-
Section 6: Memory Management
-
Section 7: Structures and Unions
-
Section 8: The Preprocessor and Build Process
-
Section 9: Standard Library: stdio.h
-
Section 10: Standard Library: stdlib.h
-
Section 11: Standard Library: string.h
-
Section 12: Standard Library: ctype.h and wctype.h
-
Section 13: Standard Library: math.h, complex.h, fenv.h, tgmath.h
-
Section 14: Standard Library: Type and Limit Headers
-
Section 15: Standard Library: Error Handling and Debugging
-
Section 16: Standard Library: Localization and Encoding
-
Section 17: Standard Library: time.h
-
Section 18: Standard Library: Concurrency (C11)
-
Section 19: POSIX and System Programming (unistd.h)
-
Section 20: More Data Structures
-
Section 21: Algorithms in C
-
Section 22: Bitwise Operations
-
Section 23: Command-Line Programs
-
Section 24: Debugging and Best Practices
-
Section 25: Compiler and Language Internals
-
Section 26: Embedded and Cross-Platform Considerations
-
Section 27: Networking Basics
-
Section 28: Practical Projects
-
Section 29: Interview Practice
-
Section 30: C23 Modern Features
-
Section 31: More Practice and Review
106: Rounding and Remainder Functions
I was working on a small inventory tool the other day, and I ran into a classic problem: calculating shipping containers. If I have 105 items and each box holds 10, I can't just ship 10.5 boxes. I need 11. If I just cast the result of a division to an integer, C will chop off the decimal, and I'll end up under-ordering boxes. Let's look at how to actually handle these "edge" cases using math.h.
The "Partial Box" Problem
First, I tried the obvious route. I divided my total items by the capacity. I used doubles because I knew I'd have a remainder.
double items = 105.0;
double capacity = 10.0;
double boxes = items / capacity; // 10.5
int final_boxes = (int)boxes; // 10
That's a bug. I've just left 5 items sitting on the warehouse floor. I need the number to always move up to the next whole number, regardless of whether the decimal is .1 or .9. This is where ceil() (short for ceiling) comes in.
#include <math.h>
#include <stdio.h>
// ... inside main ...
double boxes = 105.0 / 10.0;
printf("Boxes needed: %.f", ceil(boxes)); // Outputs: 11
I tried it with 100.0 / 10.0 as well. ceil(10.0) stayed as 10.0, which is exactly what we want. It only pushes the value up if there is any fractional part present.
Cutting off the Tail
Now, what if I want the opposite? Maybe I want to know how many completely full boxes I have. I could just cast to an int, but C provides floor() for this. For positive numbers, floor() and trunc() feel identical—they both just drop the decimal. But I noticed something strange when I tested a negative coordinate for a different project.
double val = -2.3;
printf("Floor: %.f\n", floor(val)); // Outputs: -3
printf("Trunc: %.f\n", trunc(val)); // Outputs: -2
Here's the logic: trunc() simply deletes the fractional part (it moves toward zero). floor() always moves down the number line. Since -3 is lower than -2.3, floor() goes to -3. I usually stick to floor() when doing grid-based calculations because it keeps the mathematical consistency across the zero-axis.
When the Modulo Operator Fails
Once I knew I needed 11 boxes, I wanted to find out exactly how many items were in that final, partially-filled box. Naturally, I reached for the modulo operator %.
double remainder = 105.5 % 10.0; // Compiler Error!
Right. I forgot that % only works on integers in C. If you're working with doubles—perhaps you're dealing with weights like 105.5kg—you can't use the percent sign. Instead, I have to use fmod().
double items = 105.5;
double capacity = 10.0;
double left_over = fmod(items, capacity);
printf("Remainder: %.f", left_over); // Outputs: 5.5
It's essentially the same operation, just designed to handle the precision of floating-point numbers.
The "Nearest" Dilemma
Finally, I wondered about standard rounding. Not always up, not always down, but to the nearest whole number. ceil and floor are too aggressive for that. I used round(), which follows the standard rule: .5 and above goes up, below .5 goes down.
printf("%.f\n", round(10.4)); // 10
printf("%.f\n", round(10.5)); // 11
printf("%.f\n", round(10.6)); // 11
One thing to keep in mind: all these functions return a double. If you need the result as an int for an array index or a loop counter, you'll still need to cast the result: int result = (int)round(my_val);.
📋 Practical Task
Exercise: Precision Cargo Weight Calculator
You are writing a program for a cargo drone. The drone has a maximum lift capacity of 50.0 kg per trip. You are given a total shipment weight (a double) and must calculate the following:
- The total number of trips required (this must be rounded up to the nearest whole number, as you cannot leave a fraction of a shipment behind).
- The weight of the cargo on the final trip (the remainder of the total weight divided by the capacity).
- A "rounded estimate" of the total weight for the manifest (rounded to the nearest whole number).
Requirements:
- Use
ceil(),fmod(), andround()frommath.h. - The total weight should be stored as a double (e.g., 127.4 kg).
- Print all three results clearly to the console.
There are no comments for now.