zoukankan      html  css  js  c++  java
  • 强制类型转换中的精度丢失

      最近在写unix网络程序的时候,需要完成一个很简单的程序,将输入的十六进制数转成字符串形式的IP地址,代码如下: 

     1 /*************************************************************************
     2 > File Name: hex2add.c
     3 > Author: cat
     4 > Mail: luojinfu1988@163.com
     5 
     6 ************************************************************************/
     7 
     8 #include<stdio.h>
     9 #include<stdlib.h>
    10 #include <sys/socket.h>
    11 #include <netinet/in.h>
    12 #include <arpa/inet.h>
    13 
    14 int main(int argc, char **argv)
    15 {
    16   if (argc != 2) {
    17     printf("usage: %s <addr>
    ", argv[0]);    
    18     exit(-1);
    19   }
    20 
    21   unsigned int temp = (unsigned int) strtol(argv[1], NULL, 16);
    22 
    23   struct in_addr addr;
    24   addr.s_addr = htonl(temp);
    25   printf("the ip address is %s
    ", inet_ntoa(addr));
    26 
    27   return 0;
    28 }

      但是输出的结果却不正确,0xffffffff 应该转化成 255.255.255.255 才对,为什么结果会转化错呢?

      使用gdb调试的时候发现,strtol 函数转换出问题了,strtol函数的返回值是int类型,能够表达的值达不到0xffffffff作为无符号数的值。

      比如,char 的取值范围是 -128 ~ 127, unsigned char 的取值范围是 0 ~ 255。 所以 有可能会出错。

      strtol 函数的行为有点怪,将接受到的字符串*nptr 按照无符号转换,通过前置的+ 和 - 来决定正负,而不是最高位。当转换结果相对应 int类型溢出时,就会被截断。

     1 /*************************************************************************
     2 > File Name: hex2add.c
     3 > Author: cat
     4 > Mail: luojinfu1988@163.com 
     5 
     6 ************************************************************************/
     7 
     8 #include<stdio.h>
     9 #include<stdlib.h>
    10 #include <sys/socket.h>
    11 #include <netinet/in.h>
    12 #include <arpa/inet.h>
    13 
    14 int main(int argc, char **argv)
    15 {
    16   if (argc != 2) {
    17     printf("usage: %s <addr>
    ", argv[0]);    
    18     exit(-1);
    19   }
    20 
    21   unsigned int temp = (unsigned int) strtoll(argv[1], NULL, 16); //此处我们也可以选择sscanf 函数来替换,效果更好。
    22 
    23   struct in_addr addr;
    24   addr.s_addr = htonl(temp);
    25   printf("the ip address is %s
    ", inet_ntoa(addr));
    26 
    27   return 0;
    28 }

  • 相关阅读:
    Dubbo简介
    Curator的cluster,实现多节点数据共享
    CuratorBarrier
    Curator场景应用
    Curator的监听
    Curator框架基础使用
    MySQL----MySQL数据库入门----第二章 数据库和表的基本操作
    MySQL----MySQL数据库入门----第一章 数据库入门
    PHP-----PHP程序设计基础教程----第四章数组
    PHP-----PHP程序设计基础教程----第三章函数
  • 原文地址:https://www.cnblogs.com/chenchenluo/p/4451096.html
Copyright © 2011-2022 走看看