打开浮动到字符串 [英] Turn float into string

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

问题描述

我已经着手状态,当我需要把IEEE-754的单人和双人precision数字转换成字符串与基地 10 。有一个可用 FXTRACT 指令,但它仅提供指数和尾数为基地2个,为数字的计算公式是:

 值=(-1)^ *号1(尾数)* 2 ^(指数偏置)

如果我有具体的一些基地的指令数,我就能够改变2 指数的基地 - 偏差的前pression一部分,但现在我不知道该怎么办。我也在想使用标准的圆形转化为整数,但它似乎是不可用的,因为它不提供precise转换。有谁知道什么是做它的方式/基本圣多美和普林西比?请帮忙。

我终于找到了另一种解决办法(这是在Java中)

{
    / *处理负无穷,正无穷大和NaN,返回如果'F'不是提到了一个* /
    字符串RET =;
    如果((保留= getSpecialFloats(F))。长度()!= 0)
        返回RET;
}
INT NUM = Float.toRawIntBits(F);
INT指数=(int)的(((NUM>> 23)及为0xFF)-127); // 8位,偏置127
INT尾数= NUM​​&安培; 0x7FFFFF; // 23bits/ *商店小数指数* /
INT decimalExponent = 0;
用于计算/ *临时值* /
INT sideMultiplicator = 1;
为(;指数大于0; exponent--){
    / *在这个循环中,我计算指数的值。 MAX(无符号整数)= 2 ^ 32-1,而指数可在2 ^ 127 PR ST这样的* /
    sideMultiplicator * = 2;
    正因为如此/ *,如果sideMultiplicator的前两名位被设置,我们正在越来越接近溢出,我们需要一些值保存到decimalExponent * /
    如果((sideMultiplicator>>!30)= 0){
        decimalExponent + = 3;
        sideMultiplicator / = 1000;
    }
}
为(;指数℃,;指数++){
    / *这个循环不正是相同的事情在循环之前,但反之亦然(对于指数℃下,如2 ^ -3等)* /
    如果((sideMultiplicator&放大器;!1)= 0){
        sideMultiplicator * = 10;
        decimalExponent--;
    }
    sideMultiplicator / = 2;
}/ *我们知道,浮动值为:
 * 1.mantissa * 2 ^指数*(-1)^符号* /
/ *这就是为什么我们需要存储1 betweenResult(另一temorary值)* /
INT betweenResult = sideMultiplicator;
对于(INT分数= 2位= 0;比特LT; 23;位++,部分* = 2){
    / *这个循环是最重要的:它通过把我们的指数变成了二进制尾数真正的价值* /
    如果(((尾数>>(22位))及1)== 1){
        / *如果尾数[位]时,我们需要分数来划分整数(分数为2 ^(位+ 1))* /
        而(sideMultiplicator%分数大于0&放大器;及(betweenResult>> 28)== 0){
            / *因为我们需要它之前:如果数字变近溢出,在decimalExponent店里的东西* /
            betweenResult * = 10;
            sideMultiplicator * = 10;
            decimalExponent--;
        }
        betweenResult + = sideMultiplicator /分;
    }
}/ *小转向正常化像15700号码betweenResult成157e2(存储decimalExponent变量零填充)* /
而(betweenResult%10 == 0){
    betweenResult / = 10;
    decimalExponent ++;
}
/ *这个方法(按十年或只是正常的科学,乘法)得到的字符串中reqested记号* /
返回getExponentedString(betweenResult,decimalExponent);


解决方案

格式化浮点数是相当不平凡。例如搜索对于Dragon4算法(<一个href=\"http://www.serpentine.com/blog/2011/06/29/here-be-dragons-advances-in-problems-you-didnt-even-know-you-had/\"相对=nofollow>这里是一个结果)。

非常的非常的天真,你可以试试这个:


  1. 柄楠无限。


  2. 打印符号(检查℃的)。假设今后数为正实。


  3. 如果&GT; = 1 ,截断和使用熟悉的整数格式打印的组成部分。 (应该有上具有浮点单元的硬件机器指令。)


  4. 打印小数点分隔符;现在继续乘以10和打印截断的整体数字。


  5. 当你已经达到了预期precision停止;想想正确舍入最后一位。


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)

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.

I finally found another solution (it's in 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);

解决方案

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. Handle NaN and Infinity.

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

  3. 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.)

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

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

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

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