返回顶部

收藏

化简无理数练习

更多

做初中数学题的时候经常需要把 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