gpt4 book ai didi

c - C 程序的奇怪行为::Kernighan & Ritchie 练习 2-3

转载 作者:太空宇宙 更新时间:2023-11-04 07:12:43 26 4
gpt4 key购买 nike

全部。

我编写了一个程序作为 Kernighan & Ritchie 练习 2-3 的解决方案,它在测试期间的行为(恕我直言)非常不直观。

问题规范说要编写一个程序,将十六进制值转换为十进制值。我编写的代码适用于较小的十六进制值,但对于较大的十六进制值,事情会变得有点……奇怪。例如,如果我输入 0x1234 十进制值 4660 在另一端弹出,这恰好是正确的输出(代码也适用于字母,即 0x1FC -> 508)。另一方面,如果我要输入一个大的十六进制值,例如 0x123456789ABCDEF,我应该得到 81985529216486895,虽然相反,我得到 81985529216486896(差一位数!)。

转换错误不一致,有时十进制值太高有时太低。通常,更大的十六进制值会导致十进制输出中更多不正确的位值。

这是我的完整程序:

/*Kernighan & Ritchie's Exercise 2-3

Write a function 'htoi' which converts a string of hexadecimal digits (including an
optional 0x or 0X) into its equivalent integer value.
*/
#include <stdio.h>

#define MAXLINE 1000 //defines maximum size of a hex input

//FUNCTION DEFINITIONS
signed int htoi(char c); //converts a single hex digit to its decimal value

//BEGIN PROGRAM////////////////////////////////////////////////////////////
main()
{
int i = 0; //counts the length of 'hex' at input
char c; //character buffer
char hex[MAXLINE]; //string from input
int len = 0; //the final value of 'i'
signed int val; //the decimal value of a character stored in 'hex'
double n = 0; //the decimal value of 'hex'

while((c = getchar()) != '\n') //store a string of characters in 'hex'
{
hex[i] = c;
++i;
}
len = i;
hex[i] = '\0'; //turn 'hex' into a string

if((hex[0] == '0') && ((hex[1] == 'x') || (hex[1] == 'X'))) //ignore leading '0x'
{
for(i = 2; i < len; ++i)
{
val = htoi(hex[i]); //call 'htoi'
if(val == -1 ) //test for a non-hex character
{
break;
}
n = 16.0 * n + (double)val; //calculate decimal value of hex from hex[0]->hex[i]
}
}
else
{
for(i = 0; i < len; ++i)
{
val = htoi(hex[i]); //call 'htoi'
if(val == -1) //test for non-hex character
{
break;
}
n = 16.0 * n + (double)val; //calc decimal value of hex for hex[0]->hex[i]
}
}

if(val == -1)
{
printf("\n!!THE STRING FROM INPUT WAS NOT A HEX VALUE!!\n");
}
else
{
printf("\n%s converts to %.0f\n", hex, n);
}

return 0;
}

//FUNCTION DEFINITIONS OUTSIDE OF MAIN()///////////////////////////////////
signed int htoi(char c)
{
signed int val = -1;

if(c >= '0' && c <= '9')
val = c - '0';

else if(c == 'a' || c == 'A')
val = 10;

else if(c == 'b' || c == 'B')
val = 11;

else if(c == 'c' || c == 'C')
val = 12;

else if(c == 'd' || c == 'D')
val = 13;

else if(c == 'e' || c == 'E')
val = 14;

else if(c == 'f' || c == 'F')
val = 15;

else
{
;//'c' was a non-hex character, do nothing and return -1
}

return val;
}

粘贴:http://pastebin.com/LJFfwSN5

这里发生的事情有什么想法吗?

最佳答案

您可能超出了 double 的精度可以存储整数。

我的建议是更改您的代码以使用 unsigned long long对于结果;并在此处添加溢出检查,例如:

unsigned long long n = 0; 
// ...

if ( n * 16 + val < n )
{
fprintf(stderr, "Number too big.\n");
exit(EXIT_FAILURE);
}

n = n * 16 + val;

我的小于检查有效,因为当无符号整数类型溢出时,它们回绕到零。

如果你想增加比 unsigned long long 更高的精度然后您将不得不学习更高级的技术(可能超出了 K&R 第 2 章的范围,但是一旦您读完这本书,您就可以重新访问)。


注意。您还需要 #include <stdlib.h>如果你接受我的建议exit ;并且不要忘记更改 %.0f%llu在你的决赛中 printf .此外,获取输入(K&R 涵盖)的更安全方法是:

int c;
while((c = getchar()) != '\n' && c != EOF)

我第一次在 ideone 上运行代码时遇到了段错误,因为我没有在 stdin 的末尾添加换行符所以这个循环继续将 EOF 插入 hex直到缓冲区溢出。

关于c - C 程序的奇怪行为::Kernighan & Ritchie 练习 2-3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27115039/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com