浮点的位表示?

时间:2016-02-19 10:27:14

标签: c

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

例如,为了获得数字I的二进制表示,将数字10%2的结果存储到数组中,直到数字在while循环中达到0,并且如果数组要向后打印它将以二进制表示数字。

array[] = num % 2;
num = num / 2; 

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

我也让它们在阵列中以IEEE浮点格式设置。

编辑:我必须通过使用按位比较和操作来比较两个类型的float,以查看一个数字是否大于,小于,或者它们是否与偏置指数表示法中表示的浮点数相等。具体是它通过使用从左到右的按位比较简单地比较它们的浮点表示来测试浮点数number1是否小于,等于或大于另一个浮点数number2,第一次停止时立即停止遇到不同的位。

3 个答案:

答案 0 :(得分:2)

不,它不会。将浮点数除以2将导致数字的一半如下:

#include <stdio.h>
int main(void)
{
    float x = 5.0f;
    float y = x / 2;
    printf("%f\n", y);
}

结果:

2.50000

见?它与比特无关。

浮点数的二进制表示由尾数,指数和符号位组成,这意味着与普通整数不同,您提到的技巧不会适用于此处。您可以阅读an article on Wikipedia on IEEE floating points.

了解有关详情

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

#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);
}

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

答案 1 :(得分:0)

按照你的说法不会给你一些浮点表示。而是像往常一样使用union在float和integer表示之间进行转换并打印位:

#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比较原始内存:

float f1 = 0.1;
float f2 = 0.2;
if (memcmp(&f1, &f2, sizeof(float)) == 0)
    // equal
  

概要          #include

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

说明          memcmp()函数比较内存区域s1和s2的前n个字节(每个字节被解释为unsigned char)。

     

返回值          如果找到s1的前n个字节,则memcmp()函数返回小于,等于或大于零的整数,   分别来          小于,匹配或大于s2的前n个字节。

答案 2 :(得分:0)

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

#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;
}