首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >浮点数的位表示?

浮点数的位表示?
EN

Stack Overflow用户
提问于 2016-02-19 18:27:14
回答 3查看 1.2K关注 0票数 2

我知道如何使用% 2和/2将浮点数转换为它的二进制表示形式,但是有没有更快捷、更简洁的方法呢?我正在做的事情是否被认为是按位表示一个浮点数?因为我应该在两个浮点数之间使用按位比较,但我不确定这是否意味着使用按位操作。

例如,要获得一个数字的二进制表示,我会将一个类似10%2的数字的结果存储到一个数组中,直到在while循环中这个数字达到0,如果要向后打印该数组,它将以二进制表示该数字。

代码语言:javascript
复制
array[] = num % 2;
num = num / 2; 

我所做的是对两个浮点数使用上面的方法,用它们自己的数组加载它们,并通过它们的数组对它们进行比较。

我也在它们的数组中设置了IEEE浮点格式。

编辑:我必须使用逐位比较和运算来比较两个浮点数类型的数字,看看其中一个数字是大于还是小于,或者它们是否等于用偏置指数表示法表示的浮点数。具体来说,它测试一个浮点数number1是否小于、等于或大于另一个浮点数number2,通过使用从左到右的逐位比较来简单地逐位比较它们的浮点表示,一旦遇到第一个不同位就停止。

EN

回答 3

Stack Overflow用户

发布于 2016-02-19 18:34:15

不,不会。将一个浮点数除以2会得到这个数字的一半,如下所示:

代码语言:javascript
复制
#include <stdio.h>
int main(void)
{
    float x = 5.0f;
    float y = x / 2;
    printf("%f\n", y);
}

结果:

代码语言:javascript
复制
2.50000

看见?这与bits无关。

浮点数的二进制表示由尾数、指数和符号位组成,这意味着与普通整数不同,您提到的技巧在这里不适用。您可以通过阅读an article on Wikipedia on IEEE floating points.了解更多有关这方面的信息

为了确保两个浮点数具有完全相同的位配置,您可以使用memcmp来比较它们的内容,它逐个字节地比较事物,而不需要额外的强制转换/算术/其他任何东西:

代码语言:javascript
复制
#include <stdio.h>
int main(void)
{
    float x = 5.0f;
    float y = 4.99999999999999f; //gets rounded up to 5.0f
    float z = 4.9f;
    printf("%d\n", memcmp(&x, &y, sizeof(float)) == 0);
    printf("%d\n", memcmp(&x, &z, sizeof(float)) == 0);
}

...will分别打印1和0。您也可以通过这种方式检查各个位(例如,通过在*(char*)&x上操作。

票数 2
EN

Stack Overflow用户

发布于 2016-02-19 18:39:45

按照你说的做,不会给你提供浮点表示的部分。取而代之的是使用union在浮点数和整数表示之间进行转换,并照常打印位:

代码语言:javascript
复制
#include <stdio.h>
#include <stdint.h>

typedef union {
    uint32_t i;
    float f;
} float_conv_t;

void
int_to_bin_print(uint32_t number)
{
    char binaryNumber[33];
    int i;
    for (i = 31; i >= 0; --i)
    {
        binaryNumber[i] = (number & 1) ? '1' : '0';
        number >>= 1;
    }
    binaryNumber[32] = '\0';
    fprintf(stdout, "Number %s\n", binaryNumber);
}

int main(void) {
    float_conv_t f;
    f.f = 10.34;
    int_to_bin_print(f.i);
    f.f = -10.34;
    int_to_bin_print(f.i);
    f.f = 0.1;
    int_to_bin_print(f.i);
    f.f = 0.2;
    int_to_bin_print(f.i);
    return 0;
}

输出:

编号01000001001001010111000010100100

编号11000001001001010111000010100100

编号00111101110011001100110011001101

我的目标是通过逐位比较浮点表示来比较两个浮点数。

然后,您可以使用memcmp比较原始内存

代码语言:javascript
复制
float f1 = 0.1;
float f2 = 0.2;
if (memcmp(&f1, &f2, sizeof(float)) == 0)
    // equal

提要#包含

int memcmp(const void *s1,const void *s2,size_t n);

说明memcmp()函数比较存储区s1和s2的前n个字节(每个解释为无符号字符)。

返回值如果分别发现s1的前n个字节小于、匹配或大于s2的前n个字节,memcmp()函数将返回一个小于、等于或大于零的整数。

票数 0
EN

Stack Overflow用户

发布于 2016-02-19 20:48:45

这将逐位比较两个IEEE32位float,返回-1、0或1,并指示它们不同的位。它们可以作为符号和大小的数字进行比较。下面的函数float_comp首先将它们作为uint32_t逐位比较,如果它们的符号位(第31位)不同,则取消比较。

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

static int float_comp(float f1, float f2, int *bit)
{
    const uint32_t *a, *b;
    int comp = 0;

    a = (const uint32_t *)(const void *)&f1;
    b = (const uint32_t *)(const void *)&f2;
    for (*bit = 31; *bit >= 0; (*bit)--) {
        if ((*a & (UINT32_C(1) << *bit))
             && !(*b & (UINT32_C(1) << *bit))) {
            comp = 1;
            break;
        }
        if (!(*a & (UINT32_C(1) << *bit))
             && (*b & (UINT32_C(1) << *bit))) {
            comp = -1;
            break;
        }
    }
    if (*bit == 31)
        comp = -comp;   /* sign and magnitude conversion */
    return comp;
}

int main(int argc, char **argv)
{
    float f1, f2;
    int comp, bit;

    if (argc != 3) {
        fprintf(stderr, "usage: %s: float1 float2\n", argv[0]);
        return 2;
    }
    f1 = strtof(argv[1], NULL);
    f2 = strtof(argv[2], NULL);
    comp = float_comp(f1, f2, &bit);
    if (comp == 0)
        printf("%.8g = %.8g\n", f1, f2);
    else if (comp < 0)
        printf("%.8g < %.8g (differ at bit %d)\n", f1, f2, bit);
    else
        printf("%.8g > %.8g (differ at bit %d)\n", f1, f2, bit);
    return 0;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35502962

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档