【问题标题】:Decimal to Hex conversion (C) is not working for large numbers十进制到十六进制转换 (C) 不适用于大数
【发布时间】:2017-09-21 03:00:31
【问题描述】:

我正在制作一个将十进制转换为十六进制的 C 程序。我的程序似乎适用于较小的数字,例如存储在 long int 中的 314156,但较大的数字,例如 118063104745658526495043095935640 总是返回 0x7FFFFFFF。如何处理或存储大于2147483647 / 2^32 的数字。我尝试过使用long longunsigned long long,但它们在我的代码中无法正常工作。

代码:

#include <stdio.h>
#include <stdlib.h>
int main( int argc, char* argv[] ){
    if(argc != 2 ){
        printf("Usage: %s requires one parameter\n", argv [0]);
        return 1;
    }

    unsigned long long decimal = atoi(argv[1]);
    int count = 0, count2 = 0, value = decimal;
    char hex[100];
    for( ; value!=0 ; value/=10 )
        count++;
    unsigned long long q = decimal;
    int i = 0, r = 0;
    while( q != 0){
        q = decimal/16;
        r = decimal%16; 
        printf("%*llu = %*llu * 16 + %*d (%X)\n", count, decimal, count, q, 3, r, r);
        hex[i++] = r<10 ? r+48 : r+55;
        decimal = q;
    }
    printf("0x");
    for(i-- ; i>=0; i--){
        printf("%c",hex[i]);
    }
    printf("\n");
    return 0;
}

我使用gcc 作为编译器。

【问题讨论】:

  • 使用strtoull 而不是atoi

标签: c hex decimal unsigned-long-long-int long-long


【解决方案1】:

你想要atoll(),而不是atoi()。阅读文档。

(披露:我在 atoi 停止阅读您的代码。)

【讨论】:

  • 很公平。我忘了atoll()@Dúthomhas。
  • atoll() 肯定会因输入“18446744073709551615”(2**64 - 1)而失败
  • 是的,OP 也可以使用stroull() 之类的,但是数量很大时会失败。如果他想处理任意大的数字,他必须要么获得一个 bignum 库,要么自己弄清楚如何进行处理。不管怎样,我不知道他的要求。
【解决方案2】:

我尝试过使用 long long 和 unsigned long long,但它们在我的代码中无法正常工作。

它们需要一组不同的功能。如果你使用atoi 解析一个非常大的数字,你会得到MAX_INT 值,解释0x7FFFFFFF 输出。

需要将函数替换为atoll:

unsigned long long decimal = atoll(argv[1]);

注意:这里使用“幻数”

hex[i++] = r<10 ? r+48 : r+55;

并不理想。最好写

hex[i++] = r<10 ? r+'0' : r+'A'-10;

甚至

hex[i++] = "0123456789ABCDEF"[r];

【讨论】:

  • 是的,我忘了atoll()。关于神奇数字的好技巧,我还没有看到这些方法。
【解决方案3】:

使用strtoull() 将字符串转换为unsigned long long@BLUEPIXY。当结果应为 > LLONG_MAX 时,atoll() 失败。

unsigned long long decimal = strtoull(argv[1], (char **)NULL, 10);

改变类型

unsigned long long decimal = ...;
// int  value = decimal;
unsigned long long  value = decimal;

代码在输入 "0" 时出现问题。它只是打印"0x"

改变

while( q != 0){
  ...
}

// to 

do {
  ...
} while( q != 0);

--

为清楚起见,推荐

// hex[i++] = r<10 ? r+48 : r+55;
hex[i++] = r<10 ? r+'0' : r+'A'-10;
// or 
hex[i++] = "0123456789ABCDEF"[r];

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-30
    相关资源
    最近更新 更多