How to resolve the algorithm Spelling of ordinal numbers step by step in the C programming language
How to resolve the algorithm Spelling of ordinal numbers step by step in the C programming language
Table of Contents
Problem Statement
Ordinal numbers (as used in this Rosetta Code task), are numbers that describe the position of something in a list. It is this context that ordinal numbers will be used, using an English-spelled name of an ordinal number.
The ordinal numbers are (at least, one form of them): sometimes expressed as:
For this task, the following (English-spelled form) will be used:
Furthermore, the short scale numbering system (i.e. 2,000,000,000 is two billion) will be used here. wp:Long and short scales 2,000,000,000 is two billion, not two milliard.
Write a driver and a function (subroutine/routine ···) that returns the English-spelled ordinal version of a specified number (a positive integer). Optionally, try to support as many forms of an integer that can be expressed: 123 00123.0 1.23e2 all are forms of the same integer. Show all output here.
Use (at least) the test cases of:
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Spelling of ordinal numbers step by step in the C programming language
The source code provided in C programming language is a program that calculates the ordinal or cardinal name of a given number. Here's a breakdown of what the code does:
-
Header Includes:
- The program includes necessary header files like
<stdbool.h>
,<stdio.h>
,<stdint.h>
, and<glib.h>
for various data types and functions.
- The program includes necessary header files like
-
Data Structures:
number_names
: This data structure represents the names of numbers, both in cardinal and ordinal form.named_number
: This structure stores the names and values of named numbers like "hundred," "thousand," etc.
-
Constants:
small
: An array ofnumber_names
structures representing the names of numbers from 0 to 19.tens
: An array ofnumber_names
structures representing the names of tens from 20 to 90.named_numbers
: An array ofnamed_number
structures representing named numbers like "hundred," "thousand," and their corresponding values.
-
Function Declarations:
get_small_name
: Gets the name of a small number (0-19) in either cardinal or ordinal form.get_big_name
: Gets the name of a named number like "hundred" or "thousand" in either cardinal or ordinal form.get_named_number
: Finds the named number structure corresponding to a given integer.append_number_name
: Recursively appends the name of a number to a GString.number_name
: Returns a GString containing the name of the given number in either cardinal or ordinal form.
-
Test Function and Main Function:
test_ordinal
: Tests thenumber_name
function with various numbers and prints the results.main
: Calls thetest_ordinal
function for several test cases and prints the results, demonstrating the functionality of the program.
-
Functionality:
- The
number_name
function constructs the name of a given number (up to quintillions) in either cardinal or ordinal form. - It recursively breaks down the number into small numbers (0-19), tens (20-90), and named numbers (hundred, thousand, etc.) and appends their corresponding names.
- The
test_ordinal
function showcases the program's ability to handle various numbers and display their names in ordinal form.
- The
In summary, this program demonstrates the conversion of numbers into their names, both in cardinal and ordinal form, using a combination of recursive functions, arrays of names, and named number structures.
Source code in the c programming language
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <glib.h>
typedef uint64_t integer;
typedef struct number_names_tag {
const char* cardinal;
const char* ordinal;
} number_names;
const number_names small[] = {
{ "zero", "zeroth" }, { "one", "first" }, { "two", "second" },
{ "three", "third" }, { "four", "fourth" }, { "five", "fifth" },
{ "six", "sixth" }, { "seven", "seventh" }, { "eight", "eighth" },
{ "nine", "ninth" }, { "ten", "tenth" }, { "eleven", "eleventh" },
{ "twelve", "twelfth" }, { "thirteen", "thirteenth" },
{ "fourteen", "fourteenth" }, { "fifteen", "fifteenth" },
{ "sixteen", "sixteenth" }, { "seventeen", "seventeenth" },
{ "eighteen", "eighteenth" }, { "nineteen", "nineteenth" }
};
const number_names tens[] = {
{ "twenty", "twentieth" }, { "thirty", "thirtieth" },
{ "forty", "fortieth" }, { "fifty", "fiftieth" },
{ "sixty", "sixtieth" }, { "seventy", "seventieth" },
{ "eighty", "eightieth" }, { "ninety", "ninetieth" }
};
typedef struct named_number_tag {
const char* cardinal;
const char* ordinal;
integer number;
} named_number;
const named_number named_numbers[] = {
{ "hundred", "hundredth", 100 },
{ "thousand", "thousandth", 1000 },
{ "million", "millionth", 1000000 },
{ "billion", "billionth", 1000000000 },
{ "trillion", "trillionth", 1000000000000 },
{ "quadrillion", "quadrillionth", 1000000000000000ULL },
{ "quintillion", "quintillionth", 1000000000000000000ULL }
};
const char* get_small_name(const number_names* n, bool ordinal) {
return ordinal ? n->ordinal : n->cardinal;
}
const char* get_big_name(const named_number* n, bool ordinal) {
return ordinal ? n->ordinal : n->cardinal;
}
const named_number* get_named_number(integer n) {
const size_t names_len = sizeof(named_numbers)/sizeof(named_numbers[0]);
for (size_t i = 0; i + 1 < names_len; ++i) {
if (n < named_numbers[i + 1].number)
return &named_numbers[i];
}
return &named_numbers[names_len - 1];
}
void append_number_name(GString* gstr, integer n, bool ordinal) {
if (n < 20)
g_string_append(gstr, get_small_name(&small[n], ordinal));
else if (n < 100) {
if (n % 10 == 0) {
g_string_append(gstr, get_small_name(&tens[n/10 - 2], ordinal));
} else {
g_string_append(gstr, get_small_name(&tens[n/10 - 2], false));
g_string_append_c(gstr, '-');
g_string_append(gstr, get_small_name(&small[n % 10], ordinal));
}
} else {
const named_number* num = get_named_number(n);
integer p = num->number;
append_number_name(gstr, n/p, false);
g_string_append_c(gstr, ' ');
if (n % p == 0) {
g_string_append(gstr, get_big_name(num, ordinal));
} else {
g_string_append(gstr, get_big_name(num, false));
g_string_append_c(gstr, ' ');
append_number_name(gstr, n % p, ordinal);
}
}
}
GString* number_name(integer n, bool ordinal) {
GString* result = g_string_sized_new(8);
append_number_name(result, n, ordinal);
return result;
}
void test_ordinal(integer n) {
GString* name = number_name(n, true);
printf("%llu: %s\n", n, name->str);
g_string_free(name, TRUE);
}
int main() {
test_ordinal(1);
test_ordinal(2);
test_ordinal(3);
test_ordinal(4);
test_ordinal(5);
test_ordinal(11);
test_ordinal(15);
test_ordinal(21);
test_ordinal(42);
test_ordinal(65);
test_ordinal(98);
test_ordinal(100);
test_ordinal(101);
test_ordinal(272);
test_ordinal(300);
test_ordinal(750);
test_ordinal(23456);
test_ordinal(7891233);
test_ordinal(8007006005004003LL);
return 0;
}
You may also check:How to resolve the algorithm Polyspiral step by step in the zkl programming language
You may also check:How to resolve the algorithm Remove duplicate elements step by step in the ECL programming language
You may also check:How to resolve the algorithm Primorial numbers step by step in the Julia programming language
You may also check:How to resolve the algorithm Constrained genericity step by step in the Icon and Unicon programming language
You may also check:How to resolve the algorithm Forward difference step by step in the Perl programming language