把浮点数变成字符串 [英] Turn float into string

查看:26
本文介绍了把浮点数变成字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经开始说明何时需要将 IEEE-754 单精度和双精度数字转换为具有 10 基数的字符串.有FXTRACT指令可用,但它只提供以2为底的指数和尾数,因为数字计算公式是:

I have proceeded to state when I need to turn IEEE-754 single and double precision numbers into strings with base 10. There is FXTRACT instruction available, but it provides only exponent and mantissa for base 2, as the number calculation formula is:

value = (-1)^sign * 1.(mantissa) * 2^(exponent-bias)

如果我有一些特定底数的对数指令,我将能够更改表达式中 2exponent - bias 部分的底数,但目前我不知道该怎么做.我也在考虑使用标准的舍入转换为整数,但它似乎无法使用,因为它不提供精确的转换.有谁知道这样做的方法/基本原则是什么?请帮忙.

If I had some logarithmic instructions for specific bases, I would be able to change base of 2exponent - bias part in expression, but currently I don't know what to do. I was also thinking of using standard rounded conversion into integer, but it seems to be unusable as it doesn't offer precise conversion. Does anybody know what is the way/basic principe for doing it? Please help.

我终于找到了另一个解决方案(在 Java 中)

{
    /* handling -infinity, +infinity and NaN, returns "" if 'f' isn't one of mentioned */
    String ret = "";
    if ((ret = getSpecialFloats(f)).length() != 0)
        return ret;
}
int num = Float.toRawIntBits(f);
int exponent = (int)(((num >> 23) & 0xFF)-127); //8bits, bias 127
int mantissa = num & 0x7FFFFF; //23bits

/* stores decimal exponent */
int decimalExponent = 0;
/* temporary value used for calculations */
int sideMultiplicator = 1;
for (; exponent > 0; exponent--) {
    /* In this loop I'm calculating the value of exponent. MAX(unsigned int) = 2^32-1, while exponent can be 2^127 pr st like that */
    sideMultiplicator *= 2;
    /* because of this, if top two bits of sideMultiplicator are set, we're getting closer to overflow and we need to save some value into decimalExponent*/
    if ((sideMultiplicator >> 30) != 0) {
        decimalExponent += 3;
        sideMultiplicator /= 1000;
    }
}
for(; exponent < 0; exponent++) {
    /* this loop does exactly same thing as the loop before, but vice versa (for exponent < 0, like 2^-3 and so on) */
    if ((sideMultiplicator & 1) != 0) {
        sideMultiplicator *= 10;
        decimalExponent--;
    }
    sideMultiplicator /= 2;
}

/* we know that value of float is:
 *  1.mantissa * 2^exponent * (-1)^sign */
/* that's why we need to store 1 in betweenResult (another temorary value) */
int betweenResult = sideMultiplicator;
for (int fraction = 2, bit = 0; bit < 23; bit++, fraction *= 2) {
    /* this loop is the most important one: it turns binary mantissa to real value by dividing what we got in exponent */
    if (((mantissa >> (22-bit)) & 1) == 1) {
        /* if mantissa[bit] is set, we need to divide whole number by fraction (fraction is 2^(bit+1) ) */
        while (sideMultiplicator % fraction > 0 && (betweenResult >> 28) == 0) {
            /* as we needed it before: if number gets near to overflow, store something in decimalExponent*/
            betweenResult *= 10;
            sideMultiplicator *= 10;
            decimalExponent--;
        }
        betweenResult += sideMultiplicator/fraction;
    }
}

/* small normalization turning numbers like 15700 in betweenResult into 157e2 (storing zero padding in decimalExponent variable)*/
while (betweenResult % 10 == 0) {
    betweenResult /= 10;
    decimalExponent++;
}
/* this method gets string in reqested notation (scientific, multiplication by ten or just normal)*/
return getExponentedString(betweenResult, decimalExponent);

推荐答案

格式化浮点数相当重要.搜索例如对于 Dragon4 算法(这是一个结果).

Formatting a floating point number is rather non-trivial. Search e.g. for the Dragon4 algorithm (here is one result).

非常,非常,你可以试试这个:

Very, very naively, you could try this:

  1. 处理 NaN 和无穷大.

  1. Handle NaN and Infinity.

打印标志(检查<0).假设此后该数为正实数.

Print the sign (check < 0). Assume henceforth the number is positive real.

如果>= 1,截断并使用熟悉的整数格式打印整数部分.(在任何具有浮点单元的硬件上都应该有一条机器指令.)

If >= 1, truncate and use familiar integer formatting to print the integral part. (There should be a machine instruction for that on any hardware that has a floating point unit.)

打印小数点分隔符;现在继续乘以 10 并打印截断的整数.

Print the decimal separator; now keep multiplying by 10 and print the truncated integral digit.

当您达到所需的精度时停止;考虑正确舍入最后一位数字.

Stop when you've reached the desired precision; think about rounding the last digit correctly.

这篇关于把浮点数变成字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆