如何将浮点值转换为精确精度的整数,如123.3443到1233443?

时间:2012-03-10 06:03:54

标签: c floating-point type-conversion floating-point-precision

示例代码:

int main() {
  float f = 123.542;
  int i = (int)f;
  printf("%d\n",i);
}

6 个答案:

答案 0 :(得分:10)

123.3443不能用浮点数精确表示 - 在32位浮点数中,它实际上表示为16166984 / 131072,实际上是123.34429931640625,而不是123.3443。 (大概是6.8 x 10 ^ -7。)

如果这真的是您想要的结果(可能不是这样),请看看IEEE-754如何工作,并拉出您最喜欢的任意精度数学套件。一旦你理解了“幕后”发生了什么,生成一个精确的表示不应该很难。生成“足够接近”的圆形表示实际上要困难得多。 :)

答案 1 :(得分:2)

int i = (int) (f * 10000 + 0.5);

答案 2 :(得分:0)

float乘以10^x,其中x是您想要的小数点后的位数,然后转换为int

答案 3 :(得分:0)

如果您不需要对转换后的数字进行任何重复处理,并且只想将数字转换为整数,最简单的方法是使用sprintf,然后使用for循环使用for循环求和小数。 10个规则。如果您需要数学的“精确度”,请使用BCD。以下算法将允许您截断“精确精度”的位数。

#include "math.h"

long ConvertToScaledInteger (float value, int significantDigits = -1)
{
    // Note: for 32-bit float, use long return and for double use long long.

    if (significantDigits < 1)   // Ditch the '-' and the '.'
        significantDigits += 2;
    else
        ++significantDigits;     // Ditch the '.'

    char* floatingPointString = malloc(sizeof (char) * (4 + FLT_MANT_DIG - FLT_MIN_EXP));
    /*< This solution  is for a 32-bit floating point number. Replace FLT 
         with DBL, and it will produce the max number of chars in a 64-bit 
         float string. */

    if (significantDigits < 0)   //< Then use all of the float's digits.
    {
        sprintf (floatingPointString , "%f", floatingPointNumber);
    }
    else    //< Then truncate the number of decimal places.
    {
        char decimalPlaceString[9];
        char percentString = "%\0";
        sprintf (decimalPlaceString, "%s%if", percentString , significantDigits);
        sprintf (floatingPointString , decimalPlaceString, value);
    }

    int stringLength = strlen (floatingPointString),
        index;
    long returnValue = 0;
    double powerOfTen = 10.0,
        currentValue;

    // Find if we have an ending of .0, and backtrack.
    if (floatingPointString[stringLength - 1] == '0' && floatingPointString[stringLength - 2] == '.')
        index = stringLength - 3;
    else
        index = stringLength - 1;

    for (; index > 0; --index)
    {
        if (floatingPointString[index] == '.')
            --index;

        // Subtract ASCII '0' converts ASCII to integer.

        currentValue = (double) floatingPointString[index] - '0';
        returnValue += (long) currentValue * pow (10.0, powerOfTen);

        powerOfTen += 1.0;
    }

    if (floatingPointString[0] == '-')
        returnValue *= -1;

    return returnValue;
}

答案 4 :(得分:0)

float数字f

的整数等值
float f=123.456;

可以使用modff()之类的

制作
float integral, fractional;
char str[50], temp[20];
fractional = modff(f, &integral);

现在integral具有整数部分(如123.000000),fractional具有小数部分(如0.456000)。

如果浮点数(在这种情况下为f)为负数,则integralfractional都将为负数。

你可以做到

if(fractional<0)
{
    fractional = -fractional;
}

解决这个问题。

现在,

sprintf(temp, "%g", fractional);

%g格式说明符将删除尾随零,temp现在将"0.456"

sprintf(str, "%g%s", integral, temp[1]=='.'?temp+2:"");

temp[1]=='.'?已完成,因为如果小数部分为0,那么在打印fractional时将会出现小数点,因为它会0 0.000000 1}}而不是temp。如果.中的第二个字符不是fractional,则str为零,我们不需要为此烦恼。

现在,在我们的案例中,"123456"将是strtol()。但那是一个字符串的形式。我们需要将其转换为整数。请使用long l=strtol(str, NULL, 10); if(l>INT_MAX || errno==ERANGE) { printf("\noverflow"); } else { printf("\n%d", strtol(str, NULL, 10)); }

strtol()

您可以检查errno的返回值和errno.h的返回值(来自ERANGE。检查是否为int)以查看是否发生了溢出。

要查看结果值是否可以存储在strtol()中,请首先将long int中返回的值存储在INT_MAX中,看看是否大于limits.h (它在SELECT EmployeeID FROM Employee, (SELECT AVG(Salary) avg_savary FROM Employee) sal WHERE Salary > sal.avg_savary; )。

应该注意的是,结果的准确性将取决于浮点数以二进制表示的准确度。

答案 5 :(得分:-1)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int f2i(float v, int size, int fsize){
    char *buff, *p;
    int ret;
    buff = malloc(sizeof(char)*(size + 2));
    sprintf(buff, "%*.*f", size, fsize, v);
    p = strchr(buff, '.');
    while(*p=*(p+1))p++;
    ret = atoi(buff);
    free(buff);
    return ret;
}

int main(){
    float f = 123.3443;

    printf("%d\n", f2i(f, 7, 4));

    f=123.542;
    printf("%d\n", f2i(f, 6, 3));
    return 0;
}