返回顶部

收藏

化简无理数练习

更多

做初中数学题的时候经常需要把 sqrt(20) 化成 2 * sqrt(5) 的最简形式。

但是我实在是记性不好,记不住常用数字,于是写了这个程序辅助我进行记忆。

许可证:GPL v3 或更高版本

编译时需要链接 math 库(-lm),并且最好开启 C99 支持 (-std=c99),否则可能编译失败。

程序没有异常处理机制,不要玩它就行了。

/* 做数学题的时候经常要把 sqrt(20) 化成 2 * sqrt(5) 的最简形式
 * 于是编写了这个程序来帮助我练习……
 */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

// 鄙视不用 C99 编译器的人
#ifdef __STDC_VERSION__ 
#include <stdbool.h>
#else
#define bool int
#define true 1
#define false 0
#endif

#define MIN 1    // 题目下限
#define MAX 200  // 题目上限

typedef struct
{
    /* 表示 有理数 * 根号下无理数的结构
     * 如 integer = 2, irrational = 5,即 2 * sqrt(5) */
    int integer;
    int irrational;
} intAndIrrational;

bool isEqual(double a, double b);
bool isRational(int num);
int randomInt(int start, int end);
intAndIrrational simplify(int num);

bool isRational(int num)
{
    /* 近似判断一个整数的平方根是不是有理数。
     * 如果原数截去小数部分的平方根的平方等于原数,那么认为平方根是有理数 */
    int result = ((int) sqrt((double) num) * (int) sqrt((double) num));

    if (num == result) {
        return true;
    }
    else {
        return false;
    }
}

int randomInt(int start, int end)
{
    /* 随机获取一个 start - end 之间的整数,需要实现调用 srand() 设置种子 */
    int result = rand() % end - start + 1;
    return result;
}

intAndIrrational simplify(int sqrt_num)
{
    /* 将一个无理数分解成有理数 * 根号下无理数,返回 intAndIrrational 结构
     * 若无解,intAndIrrational 中的整数部分将为 -1 */
    intAndIrrational retval;

    int i; // 鄙视不用 C99 编译器的人
    for (i = 1; i <= sqrt_num / 2; i++) {
        // 穷尽进行因数分解
        int j = sqrt_num / i;
        if (i * j == sqrt_num && isRational(j)) {
            // 找到解
            retval.integer = sqrt(j);
            retval.irrational = i;
            return retval;
        }
    }
    // 不能表示为有理数 * 无理数,无解
    retval.integer = -1;
    return retval;
}

int main(void)
{
    // 设置随机数种子
    srand((int) time(NULL));

    int max;
    printf("你想答几道题: ");
    scanf("%d", &max);
    printf("开始答题,答题格式为 a sqrt(b)\\n");

    int i; // 鄙视不用 C99 编译器的人
    for (i = 0; i < max; ++i) {
        int num = randomInt(MIN, MAX);
        intAndIrrational result = simplify(num);
        if (result.integer == -1) {
            // 无效数据
            --i;
            continue;
        }
        else if (result.irrational == 1) {
            // sqrt(1) 没有意义,跳过
            --i;
            continue;
        }
        else {
            int answer_integer;
            int answer_irrational;
            printf("\\n");
            printf("请答题:%d 分解为: ", num);
            scanf("%d sqrt(%d)", &answer_integer, &answer_irrational);

            if (answer_integer == result.integer && 
                answer_irrational == result.irrational) {
                printf("答对了!\\n");
            }
            else {
                printf("回答错误,正确答案是 %d sqrt(%d)。\\n", 
                       result.integer, result.irrational);
                continue;
            }
        }
    }
    return 0;
}
//该片段来自于http://outofmemory.cn

标签:c++,基础

收藏

0人收藏

支持

0

反对

0

相关聚客文章
  1. pansunyou 发表 2014-11-30 02:51:00 C++通用跨数据库访问方案之一: 基础组件cdbc
  2. linux@linux.cn (linu 发表 2016-11-04 02:37:00 C++ 程序员 Protocol Buffers 基础指南
  3. tanglei 发表 2014-05-28 15:08:01 struct与class区别联系
  4. 博主 发表 2016-06-28 05:17:59 Bazel C++ 基础[翻译]
  5. 博主 发表 2011-11-03 16:00:00 C++ 语言基础
  6. thinkpc 发表 2016-03-04 13:55:30 c++&nbsp;11 map基础value排序
  7. 王朝阳 发表 2013-03-01 00:00:00 旅游规划编制的基础思路
  8. mortoray 发表 2013-03-14 18:20:04 Parsing an exact decimal value using GMP
  9. Herb Sutter 发表 2012-06-05 19:03:20 GotW #104: Solution
  10. Herb Sutter 发表 2012-11-03 22:06:31 Talk now online: The Future of C++ (VC++, ISO C++)
  11. Boris Kolpackov 发表 2012-10-16 15:51:35 Custom C++ to Database Type Mapping in ODB
  12. dutor 发表 2011-10-16 14:19:12 调试基础:内存转储

发表评论