From b3e051ef5f2e15a7831cfaae6a661192c8acc623 Mon Sep 17 00:00:00 2001 From: tursom Date: Wed, 24 Mar 2021 15:36:38 +0800 Subject: [PATCH] update --- CMakeLists.txt | 2 +- bit_set.c | 50 +++-------- main.c | 236 ++++++++++++++++++++++++------------------------- time.h | 27 ++++++ 4 files changed, 158 insertions(+), 157 deletions(-) create mode 100644 time.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e51ef64..023f6c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ project(prime_numbers_c C) set(CMAKE_C_STANDARD 99) add_executable(prime_numbers_c main.c) -add_executable(bit_set bit_set.c) +add_executable(bit_set bit_set.c time.h) IF (CMAKE_SYSTEM_NAME MATCHES "Windows") target_link_libraries(prime_numbers_c) target_link_libraries(bit_set) diff --git a/bit_set.c b/bit_set.c index 235b615..5ae9ce2 100644 --- a/bit_set.c +++ b/bit_set.c @@ -4,27 +4,13 @@ #include #include #include +#include "time.h" -//#define _WIN32 - -#ifdef _WIN32 -#include -long getCurrentTime() { - LARGE_INTEGER freq; - QueryPerformanceCounter(&freq); - return (long) freq.QuadPart / 10; -} -#else - -#include - -long getCurrentTime() { - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec * 1000 * 1000 + tv.tv_usec; -} - -#endif +#define bitIndex(i) (1 << ((i) & 7)) +#define bitIsUp(arr, i) arr[(i) >> 3] & bitIndex(i) +#define bitDown(arr, i) arr[(i) >> 3] &= ~bitIndex(i) +//#define isPrime(num, bitMap) ((num) < 2 ? false : (num) == 2 ? true : !((num) & 1) ? false :\ +//bitIsUp(bitMap, (num) >> 1)) /** * 判断字符串转换为无符号整型是否会溢出 @@ -57,9 +43,9 @@ void getPrimeNumbers(unsigned long maxNumber, unsigned char *buffer) { unsigned char arr[] = {219, 182, 109}; unsigned char initIndexArr[] = {1, 2, 0}; unsigned char initIndex = 0; - unsigned char *endP = buffer + needSize; // 初始化缓冲区 + unsigned char *endP = buffer + needSize; for (unsigned char *k = buffer + 1; k < endP; ++k) { *k = arr[initIndex]; initIndex = initIndexArr[initIndex]; @@ -67,21 +53,21 @@ void getPrimeNumbers(unsigned long maxNumber, unsigned char *buffer) { *buffer = 0x6e; // 进行计算 - unsigned int sqrtMaxNumber = (unsigned int) sqrt(maxNumber) >> 1; + unsigned int sqrtMaxNumber = (unsigned int) sqrt((double) maxNumber) >> 1; maxNumber >>= 1; for (size_t i = 2; i <= sqrtMaxNumber; i++) { - if (buffer[i >> 3] & 1 << (i & 7)) { + if (bitIsUp(buffer, i)) { size_t doubleI = i + i + 1; for (size_t j = (doubleI * doubleI) >> 1; j < maxNumber; j += doubleI) { - buffer[j >> 3] &= ~(1 << (j & 7)); + bitDown(buffer, j); } } } // 去除多余结果 needSize <<= 3; - for (int l = maxNumber; l < needSize; l++) { - buffer[l >> 3] &= ~(1 << (l & 7)); + for (unsigned long l = maxNumber; l < needSize; l++) { + buffer[l >> 3] &= ~bitIndex(l); } } @@ -134,15 +120,7 @@ bool true = 1; #pragma ide diagnostic ignored "hicpp-signed-bitwise" bool isPrime(unsigned int num, const unsigned char *bitMap) { - if (num < 2) { - return false; - } else if (num == 2) { - return true; - } else if (!(num & 1)) { - return false; // 偶数 - } else { - return bitMap[num >> 4] & (1 << ((num >> 1) & 7)); - } + return num < 2 ? false : num == 2 ? true : !(num & 1) ? false : bitIsUp(bitMap, num >> 1); } #pragma clang diagnostic pop @@ -153,6 +131,7 @@ bool isPrime(unsigned int num, const unsigned char *bitMap) { int main(int argc, char *argv[]) { //必须给定最大值 if (argc <= 1) { + printf("require maximum number"); return 1; } @@ -195,7 +174,6 @@ int main(int argc, char *argv[]) { if (output) { printf(maxNum < 100001 ? "2 " : "2\n"); for (int i = 3; i <= maxNum; i += 2) { -// if (buff[i >> 4] & (1 << ((i >> 1) & 7))) { // NOLINT(hicpp-signed-bitwise) if (isPrime(i, buff)) { printf(maxNum < 100001 ? "%d " : "%d\n", i); } diff --git a/main.c b/main.c index 88c0224..dc9f29a 100755 --- a/main.c +++ b/main.c @@ -1,156 +1,152 @@ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunknown-pragmas" #pragma ide diagnostic ignored "hicpp-signed-bitwise" + #include #include #include #include -#include -#include +#include "time.h" /** * 判断字符串转换为无符号整型是否会溢出 */ int willOverFlow(char *numStr) { - static char maxValueStr[32] = {'\0'}; - static const int negative1 = -1; - static size_t lenOfMaxValue; - if (*numStr == '-')return 1; - if (!*maxValueStr) { - sprintf(maxValueStr, "%u", *(unsigned int *) &negative1); - lenOfMaxValue = strlen(maxValueStr); - } - size_t numLen = strlen(numStr); - return lenOfMaxValue < numLen ? 1 : - lenOfMaxValue > numLen ? 0 : - strcmp(maxValueStr, numStr) < 0; + static char maxValueStr[32] = {'\0'}; + static const int negative1 = -1; + static size_t lenOfMaxValue; + if (*numStr == '-')return 1; + if (!*maxValueStr) { + sprintf(maxValueStr, "%u", *(unsigned int *) &negative1); + lenOfMaxValue = strlen(maxValueStr); + } + size_t numLen = strlen(numStr); + return lenOfMaxValue < numLen ? 1 : + lenOfMaxValue > numLen ? 0 : + strcmp(maxValueStr, numStr) < 0; } size_t neededSize(unsigned long maxNumber) { - return (((maxNumber - 1) >> 4) + 1) & 0x0fffffffffffffff; + return (((maxNumber - 1) >> 4) + 1) & 0x0fffffffffffffff; } void getPrimeNumbers(unsigned int maxNumber, unsigned char *buffer) { - size_t needSize = neededSize(maxNumber); - for (int k = 1; k < needSize; ++k) { - buffer[k] = 0xff; - } - *buffer = 0xfe; - unsigned int sqrtMaxNumber = (unsigned int) sqrt(maxNumber); - for (size_t i = 3; i <= sqrtMaxNumber; i += 2) { - if (buffer[i >> 4] & 1 << ((i >> 1) & 7)) { - size_t doubleI = i + i; - for (size_t j = i + doubleI; j <= maxNumber; j += doubleI) { - buffer[j >> 4] &= ~(1 << ((j >> 1) & 7)); - } - } - } - needSize <<= 4; - for (int l = maxNumber + 1; l < needSize; l++) { - buffer[l >> 4] &= ~(1 << ((l >> 1) & 7)); - } -} - -long getCurrentTime() { - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec * 1000 * 1000 + tv.tv_usec; + size_t needSize = neededSize(maxNumber); + memset(buffer + 1, 0xff, needSize - 1); +// for (int k = 1; k < needSize; ++k) { +// buffer[k] = 0xff; +// } + *buffer = 0xfe; + unsigned int sqrtMaxNumber = (unsigned int) sqrt(maxNumber); + for (size_t i = 3; i <= sqrtMaxNumber; i += 2) { + if (buffer[i >> 4] & 1 << ((i >> 1) & 7)) { + size_t doubleI = i + i; + for (size_t j = i + doubleI; j <= maxNumber; j += doubleI) { + buffer[j >> 4] &= ~(1 << ((j >> 1) & 7)); + } + } + } + needSize <<= 4; + for (int l = maxNumber + 1; l < needSize; l++) { + buffer[l >> 4] &= ~(1 << ((l >> 1) & 7)); + } } char ByteCode(unsigned char n) { - static const char table[256] = { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, - }; - return table[n]; + static const char table[256] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, + }; + return table[n]; } void printByteMap(unsigned char n) { - printf("%d %d %d %d %d %d %d %d", - (n & 1) != 0, (n & 0x2) != 0, (n & 0x4) != 0, (n & 0x8) != 0, - (n & 0x10) != 0, (n & 0x20) != 0, (n & 0x40) != 0, (n & 0x80) != 0); + printf("%d %d %d %d %d %d %d %d", + (n & 1) != 0, (n & 0x2) != 0, (n & 0x4) != 0, (n & 0x8) != 0, + (n & 0x10) != 0, (n & 0x20) != 0, (n & 0x40) != 0, (n & 0x80) != 0); } unsigned int getPrimeCount(unsigned char *buff, size_t buffSize) { - unsigned int primeCount = 1; - for (int i = 0; i < buffSize; ++i) { - primeCount += ByteCode(buff[i]); - } - return primeCount; + unsigned int primeCount = 1; + for (int i = 0; i < buffSize; ++i) { + primeCount += ByteCode(buff[i]); + } + return primeCount; } /** * 程序入口函数 */ int main(int argc, char *argv[]) { - //必须给定最大值 - if (argc <= 1) { - return 1; - } - - //最大值 - unsigned int maxNum = 0; - if (argc > 1) { - //验证maxNum是否小于2,小于2的话计算没有意义 - //这里不能用maxNum验证,有负数的问题 - if (atol(argv[1]) < 2) { // NOLINT(cert-err34-c) - return 2; - } - - //判断最大值是否溢出 - if (willOverFlow(argv[1])) { - //如果溢出 - //输出错误提示 - printf("too large maximum number"); - //程序退出 - //返回1表示最大值溢出 - return 1; - } - - //如果都没有问题 - maxNum = (unsigned int) atol(argv[1]); // NOLINT(cert-err34-c) - } - - int output = 1; - if (argc > 2) { - output = atoi(argv[2]); // NOLINT(cert-err34-c) - } - - //分配内存,获得缓冲区; - unsigned char *buff = malloc(neededSize(maxNum)); - - //进行计算 - long t1 = getCurrentTime(); - getPrimeNumbers(maxNum, buff); - long t2 = getCurrentTime(); - //输出 - if (output) { - printf(maxNum < 100001 ? "2 " : "2\n"); - for (int i = 3; i <= maxNum; i += 2) { - if (buff[i >> 4] & (1 << ((i >> 1) & 7))) { - printf(maxNum < 100001 ? "%d " : "%d\n", i); - } - } - } - printf("\n%u numbers\nusing time:%li us, %li ms\n", - getPrimeCount(buff, neededSize(maxNum)), - t2 - t1, (t2 - t1) / 1000); - free(buff); - return 0; + //必须给定最大值 + if (argc <= 1) { + printf("require maximum number"); + return 1; + } + + //最大值 + unsigned int maxNum = 0; + if (argc > 1) { + //验证maxNum是否小于2,小于2的话计算没有意义 + //这里不能用maxNum验证,有负数的问题 + if (atol(argv[1]) < 2) { // NOLINT(cert-err34-c) + return 2; + } + + //判断最大值是否溢出 + if (willOverFlow(argv[1])) { + //如果溢出 + //输出错误提示 + printf("too large maximum number"); + //程序退出 + //返回1表示最大值溢出 + return 1; + } + + //如果都没有问题 + maxNum = (unsigned int) atol(argv[1]); // NOLINT(cert-err34-c) + } + + int output = 1; + if (argc > 2) { + output = atoi(argv[2]); // NOLINT(cert-err34-c) + } + + //分配内存,获得缓冲区; + unsigned char *buff = malloc(neededSize(maxNum)); + + //进行计算 + long t1 = getCurrentTime(); + getPrimeNumbers(maxNum, buff); + long t2 = getCurrentTime(); + //输出 + if (output) { + printf(maxNum < 100001 ? "2 " : "2\n"); + for (int i = 3; i <= maxNum; i += 2) { + if (buff[i >> 4] & (1 << ((i >> 1) & 7))) { + printf(maxNum < 100001 ? "%d " : "%d\n", i); + } + } + } + printf("\nmax number: %u, find %u prime numbers\nusing time: %li s %li ms %li us\n", + maxNum, getPrimeCount(buff, neededSize(maxNum)), + (t2 - t1) / 1000 / 1000, (t2 - t1) / 1000 % 1000, (t2 - t1) % 1000); + free(buff); + return 0; } #pragma clang diagnostic pop \ No newline at end of file diff --git a/time.h b/time.h new file mode 100644 index 0000000..c2c98f7 --- /dev/null +++ b/time.h @@ -0,0 +1,27 @@ +// +// Created by tursom on 2021/3/24. +// + +#ifndef PRIME_NUMBERS_C_TIME_H +#define PRIME_NUMBERS_C_TIME_H + +#ifdef _WIN32 +#include +long getCurrentTime() { + LARGE_INTEGER freq; + QueryPerformanceCounter(&freq); + return (long) freq.QuadPart / 10; +} +#else + +#include + +long getCurrentTime() { + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec * 1000 * 1000 + tv.tv_usec; +} + +#endif + +#endif //PRIME_NUMBERS_C_TIME_H