long转float的C语言实现

这篇博客中介绍了 float数据的二进制编码格式,因此我们可以自己写代码实现将一个长整型转换为 32位浮点数的功能。

下面是 longfloatC语言实现:

#include <stdio.h>

unsigned int count_leading_zero(unsigned long u)
{
	unsigned int n = 0;

	while (((u << n) & (1UL << 63)) == 0)
		n++;

	return n;
}

float ulong_to_float(unsigned long u)
{
	unsigned int lz = count_leading_zero(u);
	// 计算 float 指数部分的值,为(实际值 + 127),其中 127 为偏移,参见浮点数的二进制表示方法
	unsigned int e = (u != 0) ? 127U + 63U - lz : 0;

	// 将 float 尾数部分的值保存进变量 u
	u = (u << lz) & 0x7fffffffffffffffUL;

	// float 尾数部分只有 23 位,将 23 位以后的尾数部分保存进变量 t
	unsigned long t = u & 0xffffffffffUL;

	// 将 float 指数部分和尾数部分拼接在一起
	unsigned int v = (e << 23) | (unsigned int)(u >> 40);

	// 处理尾数部分的舍入逻辑:
	// 若第 24 位尾数为 1,且第 24 位尾数后的值不为 0,则第 23 位尾数 + 1
	// 若第 24 位尾数为 1,且第 24 位尾数后的值为 0,则判断第 23 位尾数是否为 1,若为 1,则第 23 位尾数 + 1
	unsigned int r = t > 0x8000000000UL ? 1U : (t == 0x8000000000UL ? v & 1U : 0U);
	unsigned int ret = v + r;

	// 将拼接后得到的二进制按照浮点数返回
	return *(float*)&ret;
}

float long_to_float(long l)
{
	long s = l >> 63;
	float r = ulong_to_float((l + s) ^ s);

	return s ? -r : r;
}

int main(void)
{
	long a = -123456789;
	printf("a = %f\n", long_to_float(a));
	printf("a = %f\n", (float)a);

	return 0;
}

程序运行结果如下所示:

$ gcc main.c -o main
$ ./main
a = -123456792.000000
a = -123456792.000000
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值