【问题标题】:C++ count the number of digits of a doubleC ++计算double的位数
【发布时间】:2010-12-02 18:19:58
【问题描述】:

我想像标题所说的那样做:

int number1;
cin>>number1;
num1len=log10(number1)+1;
cout<<"num of digits is "<<num1len<<"\n";

但当位数为 11 或更多时,答案总是7(6+1)

有谁知道我为什么或我做错了什么?

【问题讨论】:

  • 我很惊讶你得到了 7 的答案! int 将溢出,实际值为负数 - 没有 log10(),输出应为“nanv”。
  • 实际上,Nim,对 log10 的调用会悄悄地将该值转换为浮点值 - double、float 和 long double 的定义已重载。见cplusplus.com/reference/clibrary/cmath/log10
  • @Ben Voigt:从技术上讲,有符号整数溢出是未定义的行为,无论溢出有多大。
  • @Ben 是的,因为懒惰,我只输入了 12345678912,它溢出为负数......但我认为它希望能突出 OP 的意义......
  • @ephemient:从技术上讲,这不是算术溢出,而是在流提取运算符中发生转换失败。该标准要求结果是如果该字段表示的值太大而无法表示的正值,则该结果是最正的可表示值。所以我错了,它不能是任何可表示的值,尤其不能是负值。

标签: c++ double digits


【解决方案1】:

浮点数据类型,包括double,存储近似值。调用log10 会发现小数点左侧的位数,近似过程最多会影响一个位数。

你问的问题,如何找到存储在二进制浮点数中的十进制位数,是没有意义的。数字7.1 有两个十进制数字,但是它的近似浮点表示根本不使用十进制数字。要保留十进制位数,您需要一些十进制表示,而不是 C++ double 数据类型。

当然,根据问题标题,所有这些仅适用于double。您的代码 sn-p 实际上并没有使用 double。

【讨论】:

  • 是的……如果 OP 想要计算整数值中的位数,他/她将不得不考虑他/她的数据类型可以处理的最大值。跨度>
【解决方案2】:

什么是“错误”是可以存储在(有符号)int 中的最大值:

#include <iostream>
#include <numeric>

int main()
{
    std::cout << std::numeric_limits<int>::max() << std::endl;
}

给我:

2147483647

【讨论】:

    【解决方案3】:

    您正在超出无符号 32 位边界...您的 11 位或更多位数超过 0xFFFFFFFF,因此会回绕。

    您需要使用unsigned long long 或double 作为number1 变量:

    #include <iostream>
    #include <cstdlib>
    #include <cmath>
    
    int
    main ( int argc, char * argv[] )
    {
      unsigned long long num; // or double, but note comments below
      std::cin >> num;
      std::cout << "Number of digits in " << num << " is " << ( (int) std::log10 ( num ) + 1 ) << std::endl;
      return 0;
    }
    

    如果您选择使用double 作为数据类型,那么当您将这些大数字发送到std::cout 时,默认情况下它们将以科学记数法打印,因此您需要在其中进行一些格式化。如果您改用unsigned long long,它们将在输入时打印,但您必须确保您的平台支持unsigned long long。

    编辑:正如其他人所提到的,使用浮点值还有其他需要考虑的含义,并且很可能不是您最终想要实现的目标。 AFAIK,平台上产生最大正值的整数类型是unsigned long long,因此根据您要使用的值,看看它是否可供您使用。

    【讨论】:

    • 它不会环绕。行为由标准中的[facet.num.get.virtuals] 部分控制。
    • @Ben Voigt:奇怪...我使用int 进行了测试,将其编号为12345678901,然后在cout 的输出中回显的数字是-1080488104。可能是我的编译器的侥幸?或者这仅仅是因为从cin 读入时值的存储方式?
    • @Will:我正在查看 C++0x 草案标准,自 C++0x 以来可能发生了一些变化(人们希望您的编译器遵循的当前标准)。也许我可以挖掘当前的语言。只是为了验证,您是在将 std::cin 中的数字直接读入一个 32 位有符号整数变量中,而不仅仅是在源代码中执行 int n = 12345678901;,对吗?
    • @Ben Voigt:没错,就像我上面的代码示例一样。我只是好奇,因为我不经常使用 std::cin - 主要是 GUI 应用程序,所以输入通常来自 UI 控件。
    • @Will:在 C++03 中找到了部分,它是不同的。在 C++0x 中,[facet.num.get.virtuals] 指定如果转换失败,结果变量将保持不变。 OTOH C++0x 明确指定钳位行为。
    【解决方案4】:

    其他人指出浮点数是近似值,因此您无法真正获得准确的数字计数。

    但是...您可以通过将其写入 std::stringstream 对象,然后将其转换为 std::string 并获取所述字符串的长度来获得近似值。您当然必须处理字符串中可能存在非数字字符的事实(如减号、小数点、E 表示指数等)。此外,您以这种方式获得的位数将取决于您在写入 stringstream 对象时选择的格式选项。但是假设您知道要使用哪些格式选项,您可以获得受这些选项影响的位数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      • 2011-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-30
      • 1970-01-01
      相关资源
      最近更新 更多