C 为什么我不能以长数据类型存储数据?

C 为什么我不能以长数据类型存储数据?,c,types,long-integer,C,Types,Long Integer,此函数用于执行类似于计算器上的“幂”运算,因此如果我写:/a.out 5 3它将给我5到3的幂,并打印出125 问题是,如果数字是:/a.out 20 10,20乘以10的幂,我希望看到的结果是:1.024 x 10^13,但它会输出797966336 我得到的电流输出的原因是什么 注意:我假设这与atol()和long数据类型有关。这些文件不够大,不能存储信息吗?如果没有,您知道如何使其运行于更大的数字吗?首先,您需要将power()的返回类型和输入参数类型从int更改为long。否则,在lo

此函数用于执行类似于计算器上的“幂”运算,因此如果我写:
/a.out 5 3
它将给我5到3的幂,并打印出125

问题是,如果数字是:
/a.out 20 10
,20乘以10的幂,我希望看到的结果是:
1.024 x 10^13
,但它会输出
797966336

我得到的电流输出的原因是什么


注意:我假设这与
atol()
long
数据类型有关。这些文件不够大,不能存储信息吗?如果没有,您知道如何使其运行于更大的数字吗?

首先,您需要将
power()
的返回类型和输入参数类型从
int
更改为
long
。否则,在
long
int
具有不同大小的系统上

  • 传递
    long
    时,输入参数可能会被截断为
    int

  • 返回值在返回之前将被转换为
    int
    ,这可以截断实际值

  • 此后,1.024×1013(10240000000000)不能由
    int
    long
    (如果为32位)保存。您需要使用宽度更大的数据类型,例如
    long-long

    一个和两个是长的

    int power(int first,int second) {
        int counter1 = 0;
        long ret = 1;
    
        while (counter1 != second){
            ret *= first;
            counter1 += 1;
        }
        return ret;
    }
    
    
    int main(int argc,char **argv) {
    
        long one = atol(argv[1]);
        long two = atol(argv[2]);
        char word[30];
        long finally;
    
        printf("What is the operation? 'power','factorial' or 'recfactorial'\n");
        scanf("%20s",word);
    
        if (strcmp("power",word) == 0){
            finally = power(one,two);
            printf("%ld\n",finally);
            return 0;
        } 
    
    }
    
    用它们调用这个函数

    long one = atol(argv[1]);
    long two = atol(argv[2]);
    

    但是你的函数取int,这里有一个隐式转换,返回int。所以现在,你的long是int,这会导致一个未定义的行为(参见注释)。

    你可以使用长度为8字节的long-long,而不是long和int的4字节长


    long long将为您提供介于–9223372036854775808到9223372036854775807之间的值。我认为这应该涵盖您刚才可能遇到的每一个值。

    当然,您的输入是
    长的
    ,但是您的
    power
    函数接受并返回
    int
    !显然,在您的系统上是32位的…因此,在您的系统上,1.024×1013超出了
    int
    的处理能力

    确保您选择的类型足以容纳您的数据,并始终如一地使用它。即使
    很长
    也可能不够-检查您的系统

    快速回答:
    power
    函数的值被隐式转换

    将函数参数更改为其他类型,然后选择可容纳较大值的
    int
    ,一种可能的类型是
    long

    • 输入值进行类型转换和截断,以匹配函数的参数

    • 函数体中的计算结果将再次转换为与返回类型匹配,在您的情况下
      int
      :无法处理值的大小

    注1:正如经验丰富的成员所指出的,存在一个特定于机器的问题,即您的
    int
    类型没有处理通常的
    int
    应该处理的大小



    一,。要使答案完整

    代码将intlong混合在一起,并希望得到超出long范围的答案

    答案很简单,就是把10磅土豆装进5磅的袋子里


    。。。想法如何使它运行更大的数字

  • 使用可用的最宽整数。示例:
    uintmax\u t
    unsigned long-long
  • 对于C99以后的版本,通常可表示的最大整数为
    UINTMAX\u MAX

    int power(int first, int second);
    
    这种方法也有局限性。1)
    z*=base
    可以在数学上为调用pow_jululu(2100)溢出。2)
    base*base
    unsigned long
    超过
    uintmax\t
    宽度一半的罕见情况下,可能会在数学上溢出。3) 还有其他一些细微差别

  • 求助于其他类型,例如:
    长双精度
    。这可能超出了这个简单任务的范围

  • 它将在32位上溢出。不,这实际上是未定义的行为!有符号整数溢出是未定义的行为。无符号整数溢出导致换行。由于使用了
    long
    而不是
    无符号long
    ,因此在这种情况下会产生未定义的行为。(请参阅)如果包含
    限制,那么您的程序定义的
    INT\u MAX
    LONG\u MAX
    是什么?h
    ?@Olaf:我认为声称16位
    INT
    仍然比32位
    INT
    更常见是荒谬的。然而,我们仍然从时间旅行者(即,Turbo C++程序员)看到了很多。@ LexNeasraceSin轨道:大多数CPU仍然是8和16位。你完全忘记了嵌入式世界。@Olaf:我的观点是:你太过分了。当然,在野外仍然有8位和16位CPU,但是说它们基本上是“最普通的”是荒谬的!考虑到即使在嵌入式技术中,消费市场和军事市场也大多转移到32位和64位CPU。在民用工业方面还不算太多。@LightnessRacesinOrbit:想想数十亿张智能卡吧。它们中的大多数仍然使用8位或16位CPU。然后是所有隐藏的控制器:冰箱、洗衣机,甚至电视,以实现特定的功能。然后你就有了整个世界的仍然是16位(音频处理器等)的DSP。Automotive还使用许多小型CPU,例如用于LIN端点和非常高的温度。电脑键盘,鼠标。。。还有许多新的(!)工业控制项目使用8位或16位CPU。(我并没有说我支持这个;但是使用更大的芯片结构有成本和可靠性的原因)。C++没有告诉我们<代码>长长< />代码>代码>长< />代码>或<代码> int >代码>。这是特定于实现的。它可以(而且确实)因系统而异。这看起来像是吹毛求疵,但这是一种行为
    #include <stdint.h>
    
    uintmax_t power_a(long first, long second) {
      long counter1 = 0;
      uintmax_t ret = 1;
    
      while (counter1 != second){  // number of iterations could be in the billions
        ret *= first;
        counter1 += 1;
      }
      return ret;
    }
    
    // return x raised to the y power
    uintmax_t pow_jululu(unsigned long x, unsigned long y) {
      uintmax_t z = 1;
      uintmax_t base = x;
      while (y) {   // max number of iterations would bit width: e.g. 64
        if (y & 1) {
          z *= base;
        }
        y >>= 1;
        base *= base;
      }
      return z;
    }
    
    int main(int argc,char **argv) {
        assert(argc >= 3);
        unsigned long one = strtoul(argv[1], 0, 10);
        unsigned long two = strtoul(argv[2], 0, 10);
        uintmax_t finally = pow_jululu(one,two);
        printf("%ju\n",finally);
        return 0;
    }