我目前正在开发一个需要这种输出的程序:
我必须输出64位IEEE 754和C中32位数字的二进制文件。
我已经有了双浮点和单浮点近似,但是我无法找到如何以IEEE 754表示法输出这些二进制数,并对它们进行颜色编码。任何关于如何做到这一点的想法/解决方案都将非常感激。
答案 0 :(得分:4)
如果基础机器是深奥的,那么这并不能保证正确的答案:
float f = 3.14;
uint32_t u;
memcpy(&u, &f, sizeof u);
for (int i = 31; i >= 0; i--)
putchar('0' + ((u >> i) & 1));
答案 1 :(得分:2)
我决定借此机会重温我对IEE-754浮点标准的记忆。下面是我用于在其单精度浮点数表示中显示字符串的mashup,尽管它很容易被修改为双精度格式。
代码不适用于+ Inf,-Inf,NaN,尾随零,无分数和左外零(.fraction
而不是0.fraction
或integer.
而不是{{ 1}})数字,它只是给出了如何以便携和明确定义(和高度娱乐)的方式做你想做的事情的一般概念。
integer.0
使用示例:
#define EXPLEN 8 /* Fraction length for single-precision */
#define SIGNIFLEN 23 /* Significand length for single-precision */
#define EXPBIAS 0x7F /* Exponent bias for single-precision */
#define BITLEN (1 + EXPLEN + SIGNIFLEN)
BOOL strToFloat(char *floatStr, char *outBits, size_t outBitsLen){
unsigned long int floatStrLength = strlen(floatStr), intPart, fracPart, intPartHighestBit = 1, fracPartLength,
fracPartPowTen = 1, temp;
char roundBit, stickyBit, expPart = 0;
int i;
/* Get sign */
if (floatStr[0] == '-'){
floatStr++;
outBits[0] = '1';
} else {
if (floatStr[0] == '+')
floatStr++;
outBits[0] = '0';
}
if (sscanf(floatStr, "%lu.%lu", &intPart, &fracPart) == EOF ||
outBitsLen < BITLEN + 1)
return FALSE; /* Failure */
/* Get integer part */
temp = intPart;
while (temp >>= 1)
intPartHighestBit <<= 1;
for (i = EXPLEN + 1; i < BITLEN && (intPartHighestBit >>= 1); i++, expPart++)
outBits[i] = !!(intPart & intPartHighestBit) + '0';
/* Get fraction part */
fracPartLength = strlen(strchr(floatStr, '.'));
while (--fracPartLength)
fracPartPowTen *= 10;
if (!intPart && i == EXPLEN + 1)
if (fracPart > 0){
i--;
expPart--;
} else
expPart = -EXPBIAS;
for (; i < BITLEN; fracPart = (fracPart << 1) % fracPartPowTen){
outBits[i] = !!((fracPart << 1) - (fracPart << 1) % fracPartPowTen) + '0';
if (outBits[i] == '0' && i == EXPLEN) /* Start writing only after first set bit is reached if number <1 */
expPart--;
else
i++;
}
/* Get exponent part */
for (i = EXPLEN, expPart += EXPBIAS; i > 0; i--, expPart >>= 1)
outBits[i] = (unsigned char)expPart % 2 + '0';
/* Round fraction part (to-nearest mode) */
if ((fracPart << 1) - (fracPart << 1) % fracPartPowTen){ /* Guard bit set, rounding needed */
fracPart = (fracPart << 1) % fracPartPowTen;
roundBit = !!((fracPart << 1) - (fracPart << 1) % fracPartPowTen);
fracPart = (fracPart << 1) % fracPartPowTen;
stickyBit = !!((fracPart << 1) - (fracPart << 1) % fracPartPowTen);
if (roundBit || stickyBit || outBits[BITLEN - 1] == '0'){ /* Round up, add 1 to mantissa (and to exponent
if mantissa overflows)*/
for (i = BITLEN - 1; outBits[i] == '1' && i > 0; i--)
outBits[i] = '0';
outBits[i] = '1';
}
}
outBits[BITLEN] = '\0';
return TRUE; /* Success */
}
输出
char *str = "-3.14",
*outFloat = malloc(BITLEN + 1);
if (outFloat && strToFloat(str, outFloat, BITLEN + 1))
printf("%s", outFloat);
更新:尽我所能
删除幻数,因此更容易将其更改为使用双精度格式;
修复(我认为)四舍五入溢出;
修复零问题;
重构用于设置符号位的代码;而且我也在一些类型中摆弄,都是根据评论中的@ Segmented的要求。