计算一个点数的校验和。

3

我正在尝试创建一个函数,能够计算任何数字的校验和,包括浮点数。

例如:

360° = 3+6+0 = 9
180° = 1+8+0 = 9
90° = 9+0 = 9
45° = 4+5 = 9
22.5° = 2+2+5 = 9
11.25° = 1+1+2+5 = 9
5.625° = 5+6+2+5 = 18 = 1+8 = 9
2.8125° = 2+8+1+2+5 = 18 = 1+8 = 9
1.40625 = 1+4+0+6+2+5 = 18 = 1+8 = 9
0.703125 = 0+7+0+3+1+2+5 = 18 = 1+8 = 9
0.3515625 = 0+3+5+1+5+6+2+5 = 27 = 2+7 = 9
0.17578125 = 0+1+7+5+7+8+1+2+5 = 36 = 3+6 = 9
...

我写了一个小程序,用于计算整数的校验和:
#include<iostream>
using namespace std;

int checksum(int param)
{
    int sum = 0;

    while (param > 0)
    {
        sum += param % 10;
        param /= 10;
    }

    while (sum > 9) { sum = checksum(sum); } 

    return sum;
}

int main()
{
    int number = 0;

    cout<<"Enter number:"<<endl;
    cin>> number;

    cout<< checksum(number);

    cin.get(); cin.get();
    return 0;
}

如何改进它,以便它也适用于浮点数?

背景

我试图找出是否真的可以用示例中的模式来计算得到永远为9的校验和。

更新

不幸的是,C++对于这个项目来说不够精确。例如,如果我计算0.703125 / 2,那么结果将是0.3515625,但在C++中,结果是0.351563。 我的代码:http://www.pasteall.org/61345/cpp


似乎任何负参数都会产生一个校验和为0。这是有意的吗? - Christopher Oicles
2
为什么不从位表示中创建校验和? - Karoly Horvath
你想让380、180、38、18、9和90都有相同的校验和?为什么?! - David Schwartz
@DavidSchwartz?你为什么这么想? - Black
你有一个递归调用。不需要循环。 - Karoly Horvath
3个回答

2

假设你想要计算浮点数的校验和,精确到小数点后5位,那么只需将浮点数乘以100000并取整(floor),然后使用你的函数计算校验和。

编辑

由于浮点数和双精度数存在精度问题,因此最好不要使用它们来计算更多数字的校验和(对于双精度数是15位)。对于更多数字,请使用浮点数的字符串表示。


1

我从未听说过对实数求和使用校验和,你应该取二进制表示的4或8个字节,并对它们求和。这才有实际意义。


0

我自己解决了它。

输入:1.97654

输出:1.97654的校验和为5

#include<iostream>
#include<sstream>
#include<string>
#include<math.h>       /* pow */
using namespace std;

int checksum(int param)
{
    int sum = 0;


    while (param > 0)
    {
        int r1 = param % 10;
        sum += r1;
        param /= 10;
    }

    while (sum > 9) { sum = checksum(sum); } 

    return sum;
}

int main()
{
    string number; 
    cout<<"Enter number:"<<endl;
    cin>> number;

    double param_as_double      = stod(number);
    int front_part              = stoi(number);

    double after_point_part = param_as_double - front_part;

    ostringstream strs;
    strs << after_point_part;
    string after_point_part_str = strs.str();


    int nachkomma_len = after_point_part_str.length()-1;

    after_point_part *= pow(10.00,nachkomma_len-1);

    strs.str("");
    strs << after_point_part;
    after_point_part_str = strs.str();

    int after_point_part_int        = stoi(after_point_part_str);

    int SUM = 0;

    SUM = checksum(front_part);
    SUM += checksum(after_point_part_int);
    SUM = checksum(SUM);

    cout<<"The checksum of "<<number<<" is "<< SUM <<endl;

    cin.get(); cin.get();
    return 0;
}

也许这段代码比必要的还要多,但我已经很累了,因此懒得去改进它。我还没有足够的时间测试是否存在漏洞,所以不确定它是否百分之百地有效。

2
请告诉我这是为课程而非真实世界的应用程序。 - Michael Dorgan
我修改了标题,我是在谈论点数。我是德国人,不知道它的正确单词。 - Black
@DavidSchwartz它们是相同的格式。看看input: 1.97654。这是一个浮点数,那么请解释一下它为什么不是相同的格式? - Black
1
@EdwardBlack 这不是浮点数,而是十进制下的浮点数表示。1/3是浮点数吗?您是否同意“1.97654”、“1.9+0.7654”表示相同的浮点数,尽管它们是完全不同的字符串?数字是数量——无论如何表示数量都是相同的东西。“10”、“0x0A”、“9+1”和“ten”都代表同一个数字。 - David Schwartz
也许我误解了“浮点数”这个词。我只是在谈论带有小数点的数字,例如 64.78 - Black
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接