summaryrefslogtreecommitdiff
path: root/3/6_control/22_loop.c
diff options
context:
space:
mode:
Diffstat (limited to '3/6_control/22_loop.c')
-rw-r--r--3/6_control/22_loop.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/3/6_control/22_loop.c b/3/6_control/22_loop.c
new file mode 100644
index 0000000..73c7710
--- /dev/null
+++ b/3/6_control/22_loop.c
@@ -0,0 +1,51 @@
+#include <limits.h>
+#include <stdint.h>
+#include <stdio.h>
+// do
+// body
+// while (test);
+//
+// loop:
+// body
+// t = test;
+// if (t)
+// goto loop;
+
+typedef int64_t fact_t;
+
+long fact_do(long n)
+{
+ long result = 1;
+ do {
+ result *= n;
+ n = n-1;
+ } while (n > 1);
+ return result;
+}
+
+int tmult_ok(fact_t x, fact_t y)
+{
+ fact_t p = x*y;
+ return !x || p/x == y;
+}
+
+fact_t fact_do_int(size_t n)
+{
+ fact_t result = 1;
+ do {
+ if (tmult_ok(result, n)) {
+ result *= n;
+ n = n-1;
+ } else {
+ printf("would overflow this iter, n=%ld\n", n);
+ n = 0;
+ }
+ } while (n > 1);
+ return result;
+}
+
+int main(void) {
+ size_t f = 20;
+ printf("result: %ld, max: %ld, less: %d", fact_do_int(f), INT64_MAX, fact_do_int(f) < INT64_MAX);
+ return 0;
+}