From ad935287dd5d01002f726192478232b3d24f346d Mon Sep 17 00:00:00 2001 From: kdeng00 Date: Sun, 18 Oct 2020 21:49:20 -0400 Subject: [PATCH] Finished chapter 2 --- ch_02/exercise_02-09/main.c | 84 +++++++++++++++++++++++++++++++++++++ ch_02/exercise_02-10/main.c | 82 ++++++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100644 ch_02/exercise_02-09/main.c create mode 100644 ch_02/exercise_02-10/main.c diff --git a/ch_02/exercise_02-09/main.c b/ch_02/exercise_02-09/main.c new file mode 100644 index 0000000..a9993a6 --- /dev/null +++ b/ch_02/exercise_02-09/main.c @@ -0,0 +1,84 @@ +/* + * + * Exercise 2-9. In a two's complement number system, x &= (x-1) deletes the + * rightmost 1-bit in x. Explain why. Use this observation to write a faster + * version of bitcount. + * rotated to the right by n positions. + * + * Observation: + * In a two's complement number system, x &= (x-1) deletes the rightmost + * 1-bit in x. The reason for that is simple once things are broken down. + * Using an example, let's say x is 19. 19 in binary is 10011. + * (x-1) is 18 or 10010 in binary. Using the bitwise AND operator the result + * is: + * 10011 + * & 10010 + * ------- + * 10010 + * + * 10010 is 18 and 10011 with the rightmost bit removed. + * + * Author: Kun Deng + */ + + +#include +#include + + +// Counts the number of 1-bits in a number +int bitcount(unsigned int x); + +// Counts the number of 1-bits in a number but faster than bitcount() +int bitcount_improved(unsigned int x); + + +int main(int argc, char **argv) +{ + unsigned int x = 511; + + if (argc == 2) + { + x = atoi(argv[1]); + } + + int bit_amount = bitcount(x); + + printf("%d has %d bits\n", x, bit_amount); + + int bit_amount_improved = bitcount_improved(x); + + printf("%d has %d bits - Improved\n", x, bit_amount_improved); + + return 0; +} + + +int bitcount(unsigned int x) +{ + int b; + + for (b = 0; x != 0; x>>= 1) + { + if (x & 01) + { + ++b; + } + } + + return b; +} + +int bitcount_improved(unsigned int x) +{ + int b; + + // x &= (x-1) is always removing the rightmost bit. With this it's easier + // to count the amount of 1-bits simply by incrementing b. + for (b = 0; x != 0; x &= (x-1)) + { + ++b; + } + + return b; +} diff --git a/ch_02/exercise_02-10/main.c b/ch_02/exercise_02-10/main.c new file mode 100644 index 0000000..2042311 --- /dev/null +++ b/ch_02/exercise_02-10/main.c @@ -0,0 +1,82 @@ +/* + * + * Exercise 2-10. Rewrite the function lower, which converts upper case + * letters to lower case, with a conditional expression instead of + * if-else. + * + * Author: Kun Deng + */ + +#include +#include +#include + + +char lowered[50]; + +// Makes the string lower case +char *lower(char *value); + +// Returns 1 if value is a valid alphabetic value and 0 if invalid +int is_valid(char *value); + + +int main(int argc, char **argv) +{ + char *x = "soSSDFrSDGFtSGngSGDeSGD\0"; + + if (argc == 2) + { + x = argv[1]; + } + + int result = is_valid(x); + + if (result == 1) + { + printf("%s is a valid alphabetic value\n", x); + char *lowered = lower(x); + printf("%50s %10s %50s\n", "Regular", "|", "Lowered"); + printf("%50s %10s %50s\n", x, "|", lowered); + } + else if (result == 0) + { + printf("%s is not a valid alphabetic value\n", x); + } + + return 0; +} + +char *lower(char *value) +{ + extern char lowered[]; + int result = 0; + int a; + + for (a = 0; value[a] != '\0'; ++a) + { + char c = value[a]; + // printf("%c ", c); + lowered[a] = (isupper(c) ? tolower(c) : c); + } + + lowered[a] = '\0'; + + return lowered; +} + +int is_valid(char *value) +{ + int result = 1; + + for (int i = 0; value[i] != '\0'; ++i) + { + if (!isalpha(value[i])) + { + result = 0; + break; + } + } + + return result; +}