C语言中memcmp函数可以用来比较两个浮点数大小吗?

C语言 码拜 8年前 (2016-01-30) 1908次浏览
比较两个浮点数完全不用这么麻烦,但本人只是想深入了解一下memcmp的功能。
本人发现可以用memcmp比较浮点数,但输出结果有问题:

#include <stdio.h>
#include <string.h>
int main( void ) {
    double a = 1.0;
    double b = 2.0;
    double *aPtr, *bPtr;
    aPtr = &a;
    bPtr = &b;
    printf( "%d", memcmp( aPtr, bPtr, 8 ) );
return 0;
}

这个程序结果是1,但1.0<2.0不应该是-1吗?

解决方案:37分
解决这个问题需要了解两个方面的知识
1、memcmp函数的意义
2、double数据类型在内存中的表示

1、memcmp函数的意义
比较前n个字节的大小。

2、double数据类型在内存中的表示
为了更好地理解,下面把double类型的 1.0 和 2.0 在内存中的表示以十六进制的形式列出来
1.0 ==  00-00-00-00-00-00-F0-3F
2.0 ==  00-00-00-00-00-00-00-40
从上面的内存表示可以很容易知道为什么1.0和2.0用memcmp函数比较之后反而是1.0大了。
那么接下来的问题就是1.0和2.0为什么在内存中就是那么表示的。
(1)先将1.0和2.0分别用二进制的科学计数法表示
1.0   ==  1.0乘以(2的0次方)
2.0   ==  1.0乘以(2的1次方)
* 规定 double 在内存中以三个部分存储:符号、阶码、尾数
* 符号占1位、阶码占11位、尾数点52位
* 由于尾数的小数点之前都是数字1,所以规定小数点之前的数字1不必存储,也就是说尾数只需要存储小数点之后的数值即可
* 正数的符号为0  负数的符号为1
* 规定阶码存储时需要加上1023
所以,1.0的阶码0,加上1023之后是1023,二进制表示为  0111 1111 111
2.0的阶码1,加上1023之后是1024,二进制表示为  1000 0000 000
由于 1.0 和 2.0 的符号位、尾数都是0
所以, 1.0 ==  0(符号位) 0111 1111 111(十一位阶码) (此处省略五十二位尾数0)
2.0 ==  0(符号位) 1000 0000 000(十一位阶码) (此处省略五十二位尾数0)

写成十六进制的形式为  1.0 == 3F-F0-00-00-00-00-00-00
2.0 == 40-00-00-00-00-00-00-00
最后,由于一般计算机中内存以小端存储,也就是数值的高字节反而是放在后面的。
所以在内存中的表示为  1.0 == 00-00-00-00-00-00-F0-3F
2.0 == 00-00-00-00-00-00-00-40


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明C语言中memcmp函数可以用来比较两个浮点数大小吗?
喜欢 (0)
[1034331897@qq.com]
分享 (0)