/*
* Copyright ©2026 Soham Pardeshi. All rights reserved.
* Permission is hereby granted to students registered for University of
* Washington CSE 333 for use solely during Summer Quarter 2026 for
* purposes of the course. No other use, copying, distribution, or
* modification is permitted without prior written consent. Copyrights
* for third-party components of this work must be honored. Instructors
* interested in reusing these course materials should contact the author.
*/
#include <stdio.h> // for printf
#include <stdlib.h> // for strtol, EXIT_SUCCESS / EXIT_FAILURE
#include <string.h> // for strlen
// Print out the given string to stderr with an error prefix
void LogError(const char* error_text);
// Print out the usage of the program to stderr
void LogUsage(void);
// Return the nth fractional term in the Nilakantha series.
double GetNthTerm(int n);
int main(int argc, char* argv[]) {
// [Precheck]
// Verify that the user only passed one input via the command line
if (argc != 2) {
LogUsage();
return EXIT_FAILURE;
}
// [Precheck]
// Verify that the user gave us an integer value.
// Although strtol returns a long, we can assume it is an int from the spec
char* end_ptr;
int num_terms = strtol(argv[1], &end_ptr, 10);
// [Edge Case]
// What happens if the user types in "10abc" or "10.5"? In that case, strtol
// will parse the "10" and stop at the first non-integer character. We can
// check for this by comparing these two pointers:
//
// - `end_ptr` points to the last character that strtol was able to parse
// - `end_arg_ptr` points to the last character in argv[1]
//
// If they are pointing to different characters, then strtol was not able to
// parse the entire string as a single integer value.
char* end_arg_ptr = argv[1] + strlen(argv[1]);
if (end_ptr != end_arg_ptr) {
LogError("User provided a non-integer value.");
LogUsage();
return EXIT_FAILURE;
}
// [Precheck]
// Verify that the integer isn't negative.
if (num_terms < 0) {
LogError("User provided a negative integer value.");
LogUsage();
return EXIT_FAILURE;
}
// Calculate and print the estimate.
double estimate = 3.0;
for (int i = 1; i <= num_terms; ++i) {
estimate += GetNthTerm(i);
}
printf("Our estimate of Pi is %.20f\n", estimate);
return EXIT_SUCCESS;
}
void LogError(const char* error_text) {
fprintf(stderr, "ERROR: %s\n", error_text);
}
void LogUsage(void) {
fprintf(stderr,
"Usage:\n"
" ./ex1 n\n"
"where n is a non-negative integer.\n"
"Prints an estimate for Pi using n terms "
"of the Nilakantha series.\n");
}
double GetNthTerm(int n) {
double numerator = 4.0;
double denominator = (2.0 * n) * (2.0 * n + 1.0) * (2.0 * n + 2.0);
double term = numerator / denominator;
if (n % 2 == 0) {
term *= -1.0;
}
return term;
}