【问题标题】:Calculate checksum of a point number计算点号的校验和
【发布时间】:2015-09-25 19:57:04
【问题描述】:

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

例如:

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 的校验和。这是有意的吗?
  • 为什么不从位表示创建校验和?
  • 您希望 380、180、38、18、9 和 90 都具有相同的校验和?为什么?!
  • @DavidSchwartz ?是什么让你这么认为?
  • 你有一个递归调用。不需要循环。

标签: c++ numbers checksum


【解决方案1】:

假设您要计算浮点数的小数点后 5 位的校验和,然后只需将浮点数乘以 100000 并取“下限”,然后用您的函数计算校验和。

编辑

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

【讨论】:

    【解决方案2】:

    我从未听说过通过对数字求和来对实数进行校验和。您应该采用二进制表示,4 或 8 个字节,并将它们相加。那会很有意义。

    【讨论】:

      【解决方案3】:

      我自己解决了。

      输入: 1.97654

      输出: The checksum of 1.97654 is 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;
      }
      

      可能需要更多的代码,但我很累,因此懒得改进它。我还没有足够的时间来测试它的错误,所以我不确定它是否能 100% 工作。

      【讨论】:

      • 请告诉我这是针对课程而非现实世界的应用程序。
      • 这不计算浮点数的校验和,它计算字符串的校验和。
      • 我编辑了标题,我在谈论点数。我是德国人,不知道合适的词。
      • @EdwardBlack 它们的格式完全不同。其中一个是数字,另一个是表示。他们甚至不属于同一类别。
      • @EdwardBlack 这不是一个浮点数,它是一个以十为底的浮点数的表示。 1/3 是浮点数吗?您是否同意“1.97654”、“1.9+0.7654”表示相同的浮点数,即使它们是完全不同的字符串?数字就是金额——无论金额如何表示,它都是一样的。 “10”、“0x0A”、“9+1”和“十”都代表同一个数字。
      猜你喜欢
      • 2010-12-01
      • 2015-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-08
      • 1970-01-01
      • 2021-05-11
      相关资源
      最近更新 更多