【问题标题】:About Integer Datatypes and Promotions关于整数数据类型和促销
【发布时间】:2013-11-17 04:21:04
【问题描述】:
  • 平台:Linux 3.2.0 x86 (Debian 7.1)
  • 编译器:GCC 4.7.2 (Debian 4.7.2-5)

我正在编写一个整数到字符串的转换函数,它接受一个整数值(基数)作为参数。整数参数(基数)的有效范围非常小(2-36),小于字符的最大大小。所以我想将参数声明为 char 但我必须将 long long int 乘以所述参数,我想知道它是如何工作的。我不想将参数声明为 char 如果这会给计算过程增加任何额外内容。所以我的问题是当我将一个 long long int 乘以一个关于计算本身的 char 时会发生什么。此外,该函数会写入少量数据,在最坏的情况下小于 unsigned char 的最大大小,因此我想使用短 int 对其进行索引,因为当我尝试使用 char 取消引用指针时会收到警告。所以我的问题是为什么指针不能被 char 取消引用,并且当我将索引的值增加或减少 1 时,使用 short int 作为索引是否会在取消引用过程或计算过程中添加任何内容。这些行为是否一致,因为我听说某些系统上的 16 位整数数据类型在算术方面实际上比 32 位对应的数据类型效率低,但我不知道这是不是真的。

int integer_conversion(long long int integer, char *str, short int str_size, char radix)
{
    //'i' is the index variable I was talking about.
short int i = 1;
long long int radix_place = 1;

if(str == NULL) return -1;
if(str_size <= 0) return -2;

if(integer < 0)
{
            //radix_place(long long int) * radix(char)
    for(; integer / radix_place <= -radix; radix_place *= radix, i++);
    i++;

    if(i > str_size) return -4;

    str[i] = '\000';
    i--;

    if(radix >= 2 && radix <= 10)
    {
        for(; i >= 1; i--)
        {
                            //integer(long long int) mod radix(char)
            str[i] = -(integer % radix) + '0';
                            //integer(long long int) / radix(char)
            integer /= radix;
        }
    }
    else if(radix >= 11 && radix <= 36)
    {
        for(; i >= 1; i--)
        {
                            //integer(long long int) mod radix(char)
            str[i] = -(integer % radix);

                            //Is any type of conversion or promotion preformed here?
            if(str[i] <= 9) str[i] += '0';
            else str[i] += '7';

                            //integer(long long int) / radix(char)
            integer /= radix;
        }
    }
    else return 2354;

    str[0] = '-';
}
else
{
            //radix_place(long long int) * radix(char)
    for(; integer / radix_place >= radix; radix_place *= radix, i++);

    if(i > str_size) return -4;

    str[i] = '\000';
    i--;

    if(radix >= 2 && radix <= 10)
    {
        for(; i >= 0; i--)
        {
                            //integer(long long int) mod radix(char)
            str[i] = integer % radix + '0';
                            //integer(long long int) / radix(char)
            integer /= radix;
        }
    }
    else if(radix >= 11 && radix <= 36)
    {
        for(; i >= 0; i--)
        {
                            //integer(long long int) mod radix(char)
            str[i] = integer % radix;

                            //Is any type of conversion or promotion preformed here?
            if(str[i] <= 9) str[i] += '0';
            else str[i] += '7';

                            //integer(long long int) / radix(char)
            integer /= radix;
        }
    }
    else return 2354;
}

return 0;
}

【问题讨论】:

  • 不要担心效率——尤其是选择正确大小的整数的效率——直到您编写了代码并且实际上需要使其更高效。过早的优化是万恶之源。
  • @Aniket 你说得对,我刚刚更新了这个问题。 jwodder 该功能已完成大部分。

标签: c


【解决方案1】:

两部分:

  1. 效率。在现代处理器上,在大多数地方(例如函数参数和局部变量)声明比int 更短的类型并没有提高效率。如果您正在为小型微控制器编写代码,也许charunsigned char 参数会很有用。

  2. 正确性。所有整数类型(包括char)将首先被提升为int,除非它们不适合,在这种情况下它们将被提升为unsigned int,除非它们不适合。然后“通常的算术转换”将大多数操作中的两种类型提升为相同的类型。

这是一个例子:

char c;
long long x;
return c * x;

在这种情况下,结果是:

return ((long long) c) * x;

(除非,sizeof(long long) == 1CHAR_BIT == 64char 在默认情况下是未签名的。但这是一个彻头彻尾的病态案例。)

推荐

使用int 而不是short

int integer_conversion(long long int integer, char *str, int str_size, int radix)
{
    // don't bother with "short"
    int i = 1;
    long long int radix_place = 1;

    if(str == NULL) return -1;
    if(str_size <= 0) return -2;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-08
    • 1970-01-01
    • 1970-01-01
    • 2010-11-22
    • 2020-10-29
    • 2023-03-25
    相关资源
    最近更新 更多