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
94: Integer Arithmetic Helpers: abs, div, labs
Imagine you're managing a warehouse. Sometimes, you don't care if a shipment was an "overage" (too many items arrived) or a "shortage" (not enough arrived); you just want to know the magnitude of the error to figure out how much paperwork to file. Whether it's -5 boxes or +5 boxes, the "error" is simply 5. That's your absolute value.
Now, imagine you have a pallet of 53 widgets and you need to pack them into boxes of 10. You need to know two things simultaneously: how many full boxes you can ship, and how many loose widgets are left over. You could do this in two separate steps, but it's more efficient to just "do the division" once and get both answers at the same time.
Stripping the Sign with abs and labs
In C, when we want that "magnitude" regardless of the sign, we use the functions found in <stdlib.h>. For standard integers, you've got abs(). If you're dealing with those massive numbers stored in a long, you use labs().
#include <stdio.h>
#include <stdlib.h>
int main() {
int shortage = -15;
long huge_debt = -1234567890123L;
int magnitude = abs(shortage);
long total_debt = labs(huge_debt);
printf("Error magnitude: %d\n", magnitude); // 15
printf("Debt magnitude: %ld\n", total_debt); // 1234567890123
return 0;
}
I should give you a heads-up on a classic C gotcha here: abs() returns the same type it takes. Because of how two's complement binary works, the most negative number possible (like INT_MIN) doesn't have a corresponding positive number that fits in the same type. If you try to abs() the absolute minimum integer, you'll get undefined behavior. In a real production system, I'd always check if the value is INT_MIN before calling abs() if the data is coming from an untrusted source.
Getting the Quotient and Remainder in One Shot
Usually, you'd use the / operator for the quotient and the % operator for the remainder. But if you're doing both, you're essentially asking the CPU to do the same hard work twice. The div() function (and its cousins ldiv() for longs) solves this by returning a struct called div_t.
The div_t struct is simple; it just contains two members: quot and rem.
#include <stdio.h>
#include <stdlib.h>
int main() {
int total_widgets = 53;
int box_size = 10;
div_t result = div(total_widgets, box_size);
printf("Full boxes: %d\n", result.quot); // 5
printf("Leftover widgets: %d\n", result.rem); // 3
return 0;
}
You might wonder, "Why bother with a struct when I can just use / and %?" On some older architectures or specific embedded chips, the division instruction actually calculates both the quotient and the remainder in a single cycle and stores them in different registers. Using div() tells the compiler it's okay to use that optimization. Modern compilers are incredibly smart and often optimize / and % into a single operation anyway, but using div() makes your intent explicit and keeps your code portable across different levels of hardware optimization.
📋 Practical Task
Building a Budget Variance Calculator
You are tasked with writing a small utility for an accounting app. The program needs to take a "Target Budget" and an "Actual Spend" and calculate the variance.
Write a program that does the following:
- Defines two
longvariables:target_budgetandactual_spend. - Calculates the raw difference (
actual_spend - target_budget). - Uses
labs()to determine the absolute variance (the total amount the budget was off, regardless of over or under). - Uses
ldiv()to determine how many full "Quarterly Installments" (divide the absolute variance by 4) the correction would take, and how much the "Remaining Adjustment" would be for the final installment. - Prints the absolute variance, the number of full installments, and the remaining adjustment.
There are no comments for now.