I wanted to extend the Imperial/metric converter further, by adding feet to the cm to inches conversion, so human heights could be displayed in a "6ft, 2in" style. It still needs the maths debugging for the whole 6 feet value remainder issue as shown:

I struggled with the logic and units for ages with this, as I knew I had to convert the fractional part of a foot to inches but did not know how to modify the modulus for integers (x%y) for float values to strip away the fraction then convert that back to imperial and "add it" back to the larger foot value as a rounded nearest inch.

I finally found an example explaining it needs the math.h lib – as other functions like power, square root, sin etc. do – and the simple format of remainder = fmod(dividend, divisor);

This resulted in the following extended code:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
case '4': printf("Want to convert (c) cm to inches/feet or (i) inches to cm?: "); fgets(line, sizeof(line), stdin); sscanf(line, "%c", &operator); switch (operator) { case 'c': printf("c: convert cm to inches. Enter cm value: "); fgets(line, sizeof(line), stdin); sscanf(line, "%f", &cm); inches = cm * 0.393701; feet = inches/12; remaining = fmod(inches,12); printf("%0.2f cm is %0.2f inches, or %0.0fft,%0.0lf ins! \n\n", cm,inches,feet,remaining); break; case 'i': printf("i: convert inches to cm. Enter inches value: "); fgets(line, sizeof(line), stdin); sscanf(line, "%f", &inches); cm = 1/0.393701*inches; feet = inches/12; remaining = fmod(inches,12); printf("%0.0f \n", remaining); printf("%0.1f inches is %0.1f cm or %0.0fft,%0.0lf ins! \n\n", inches,cm,feet,remaining); } break; default: { printf("Invalid key, try again! %c\n\n", operator); |

etc…

To see how the maths works in the section:

1 2 3 4 5 6 7 8 |
printf("i: convert inches to cm. Enter inches value: "); fgets(line, sizeof(line), stdin); sscanf(line, "%f", &inches); cm = 1/0.393701*inches; feet = inches/12; remaining = fmod(inches,12); printf("%0.0f \n", remaining); /*temp test line to show the actual result of the fmod */ printf("%0.1f inches is %0.1f cm or %0.0fft,%0.0f ins! \n\n", inches,cm,feet,remaining); |

The input is in inches in the first sub menu above, so that is converted to cm first as a fixed value.

The rounded nearest feet value is also converted as a fixed value.

To find the fractions of a foot, the fmod gives the excess ("* float remaining;*" declaration) as a decimal for inch values that are not exact multiples of 12. This remainder modulus of a foot is truncated or rounded to the nearest inch by allowing only a 0 decimal place float holder as %0.0f.

For example, 24 inches shows no "remaining" when fmod'd by 12, giving a 0 ins result, but 14 inches has a remainder 2.

The conversions are not exact but adequate, as 12.5 inches gets rounded down** **to 1ft, 0 in; and 12.6 inches gets rounded up to 1ft, 1 in. Ideal for this exercise.

I can now look at modifying the kg/pounds case for ounces in a similar way.

I tested the same values in reverse to check they were rounded closely enough to make sense below i.e. 33cm = 13ins = 12.99ins

This case 4 sub menu section now outputs:

./unitsconverter2

program to convert Imperial units to metric. Enter menu option:

1: km to miles

2: litres to pints

3: kg to pounds

4: cm to inches

q: quit

4

Want to convert (c) cm to inches/feet or (i) inches to cm?: i

i: convert inches to cm. Enter inches value: 13

1

**13.0 inches** is 33.0 cm or **1ft,1 ins!**

program to convert Imperial units to metric. Enter menu option:

1: km to miles

2: litres to pints

3: kg to pounds

4: cm to inches

q: quit

4

Want to convert (c) cm to inches/feet or (i) inches to cm?: i

i: convert inches to cm. Enter inches value: 72

0

72.0 inches is 182.9 cm or **6ft,0 ins!**

program to convert Imperial units to metric. Enter menu option:

1: km to miles

2: litres to pints

3: kg to pounds

4: cm to inches

q: quit

4

Want to convert (c) cm to inches/feet or (i) inches to cm?: i

i: convert inches to cm. Enter inches value: 65

5

65.0 inches is 165.1 cm or **5ft,5 ins!**

program to convert Imperial units to metric. Enter menu option:

1: km to miles

2: litres to pints

3: kg to pounds

4: cm to inches

q: quit

4

Want to convert (c) cm to inches/feet or (i) inches to cm?: c

c: convert cm to inches. Enter cm value: 33

33.00 cm is **12.99 inches**, or **1ft,1 ins!**

program to convert Imperial units to metric. Enter menu option:

1: km to miles

2: litres to pints

3: kg to pounds

4: cm to inches

q: quit

4

Want to convert (c) cm to inches/feet or (i) inches to cm?: c

c: convert cm to inches. Enter cm value: 184

184.00 cm is 72.44 inches, or **6ft,0 ins!**

program to convert Imperial units to metric. Enter menu option:

1: km to miles

2: litres to pints

3: kg to pounds

4: cm to inches

q: quit

w

Invalid key, try again! w

program to convert Imperial units to metric. Enter menu option:

1: km to miles

2: litres to pints

3: kg to pounds

4: cm to inches

q: quit

q

**8/9/16 Just revisited this for revision and the answer to the incorrect 6ft problem is a simple rounding up issue solved by defining feet as an integer to round it down to correct feet; not a float! Duh…**

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
case '4': printf("Want to convert (c) cm to inches/feet or (i) inches to cm?: "); fgets(line, sizeof(line), stdin); sscanf(line, "%c", &operator); switch (operator) { case 'c': printf("c: convert cm to inches. Enter cm value: "); fgets(line, sizeof(line), stdin); sscanf(line, "%f", &cm); inches = cm/2.54; feet = inches/12; remaining = fmod(inches,12); printf("%0.1f cm is %0.1f inches, or %dft,%0.00f ins \n\n", cm,inches,feet,remaining); break; case 'i': printf("i: convert inches to cm. Enter inches value: "); fgets(line, sizeof(line), stdin); sscanf(line, "%f", &inches); cm = inches*2.54; feet = inches/12; remaining = fmod(inches,12); printf("%0.0f \n", remaining); printf("%0.1f inches is %0.1f cm or %dft,%0.00f ins \n\n", inches,cm,feet,remaining); } break; |

The full version incl. ounces and yards is here:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
/*units converter2.c with extra menus for dist, vol or mass conversion*/ #include <stdio.h> #include <math.h> float remaining; float km; /*= 1;*/ float miles; /*= 1.60934 * km ;*/ float yards; /*1760*/ float litre; /*= 1;*/ float pints; /*= (1.75975 / litre);*/ float gallons; /*= (8 * pints);*/ float kg; /*= 1;*/ float lbs; /* = (2.204622 * kg);*/ float ounces; /*16/lb*/ float inches; /*m = (3.28084*12) */ int feet; /*m = 3.28084 ft */ float cm; /* = 0.393701 inches*/ float finches; /*remainder of inch/12 = 0.083333333 */ char line[10]; /*input value array space */ char operator; /* menu operator the user specified */ float value; /* input value the user specified */ float result; int main() { while (1) { printf("program to convert Imperial units to metric. Enter menu option: \n"); printf("1: km to miles\n"); printf("2: litres to pints\n"); printf("3: kg to pounds\n"); printf("4: cm to inches\n"); printf("q: quit\n"); fgets(line, sizeof(line), stdin); sscanf(line, "%c", &operator); if ((operator == 'q') || (operator == 'Q')) break; switch (operator) { case '1': printf("Want to convert (k) km to miles or (m) miles to km?: "); fgets(line, sizeof(line), stdin); sscanf(line, "%c", &operator); switch (operator) { case 'k': printf("k: convert km to miles/yards. Enter km value: "); fgets(line, sizeof(line), stdin); sscanf(line, "%f", &km); miles = km / 1.60934; yards = miles*1760; printf("%f km is %0.2f miles or %0.2f yards\n\n",km,miles,yards); break; case 'm': printf("m: convert miles to km. Enter miles value: "); fgets(line, sizeof(line), stdin); sscanf(line, "%f", &miles); km = miles * 1.60934; yards = miles*1760; printf("%0.2f miles is %0.2f yards or %0.2f km\n\n",miles,yards,km); break; } break; case '2': printf("Want to convert (l) litres to pints or (p) pints to litres?: "); fgets(line, sizeof(line), stdin); sscanf(line, "%c", &operator); switch (operator) { case 'l': printf("l: convert litres to pints. Enter litre value: "); fgets(line, sizeof(line), stdin); sscanf(line, "%f", &value); result = value * 1.75975; gallons = result/8; printf("%0.2f litres is %0.2f pints or %0.2f gallons\n\n", value, result, gallons ); break; case 'p': printf("p: convert pints to litres. Enter pints value: "); fgets(line, sizeof(line), stdin); sscanf(line, "%f", &value); result = value / 1.75975; gallons = result*1.75975/8; printf("%0.2f pints is %0.2f litres or %0.2f gallons\n\n", value, result, gallons ); break; } break; case '3': printf("Want to convert (k) kg to pounds or (p) pounds to kg?: "); fgets(line, sizeof(line), stdin); sscanf(line, "%c", &operator); switch (operator) { case 'k': printf("k: convert kg to pounds/ounces. Enter kg value: "); fgets(line, sizeof(line), stdin); sscanf(line, "%f", &kg); lbs = kg * 2.204622; ounces = lbs*16; printf("%0.2f kg is %0.2f ounces or %0.2f pounds or \n\n", kg,ounces,lbs); break; case 'p': printf("p: convert pounds to kg. Enter pounds value: "); fgets(line, sizeof(line), stdin); sscanf(line, "%f", &lbs); kg = lbs / 2.204622; ounces = lbs*16; printf("%0.2f lb is %0.2f ounces or %0.2fkg \n\n", lbs,ounces,kg); } break; case '4': printf("Want to convert (c) cm to inches/feet or (i) inches to cm?: "); fgets(line, sizeof(line), stdin); sscanf(line, "%c", &operator); switch (operator) { case 'c': printf("c: convert cm to inches. Enter cm value: "); fgets(line, sizeof(line), stdin); sscanf(line, "%f", &cm); inches = cm/2.54; feet = inches/12; remaining = fmod(inches,12); printf("%0.1f cm is %0.1f inches, or %dft,%0.00f ins \n\n", cm,inches,feet,remaining); break; case 'i': printf("i: convert inches to cm. Enter inches value: "); fgets(line, sizeof(line), stdin); sscanf(line, "%f", &inches); cm = inches*2.54; feet = inches/12; remaining = fmod(inches,12); printf("%0.0f \n", remaining); printf("%0.1f inches is %0.1f cm or %dft,%0.00f ins \n\n", inches,cm,feet,remaining); } break; default: { printf("Invalid key, try again! %c\n\n", operator); break; } } } printf("\n"); /*tidy cmd line*/ return (0); } |