如何将双精度或浮点数(所有数字)转换为整数?

时间:2019-03-06 05:37:46

标签: c++ floating-point

如何将双精度或浮点数(所有数字)转换为整数?

例如,如果我有一个双0.9332,该函数将返回9332, 1.32001将返回132001

5 个答案:

答案 0 :(得分:0)

this will work ! question is similar to this one :
https://stackoverflow.com/questions/5314954/how-to-get-the-length-of-a-numbers-fraction-part

#include <iostream>
#include <math.h>
using namespace std;
int getFractionDigitsCount(float );
int main()
{
    float a=1.9332;
    int p = getFractionDigitsCount(a);
    cout<<"answer is : "<< a * pow(10,p);

    return 0;
}
 int getFractionDigitsCount(float d) {
    if (d >= 1) { //we only need the fraction digits
        d = d - (long) d;
    }
    if (d == 0) { //nothing to count
        return 0;
    }
    d *= 10; //shifts 1 digit to left
    int count = 1;
    while (d - (long) d != 0) { //keeps shifting until there are no more fractions
        d *= 10;
        count++;
    }
    return count;
}

答案 1 :(得分:0)

再想一想,由于浮点数的限制,您不能通过简单的强制转换和乘法来将echo “deployApps=@(Projectname)” >> $DeployPropertiesSrc (或double)的直接转换优雅地处理为整数点数不能完全代表所有导致重复小数点等的值,这会导致小数部分方法的乘法运算对于float之类的数会失败。

但是,您可以使用中间的9.999999并解析字符串中的数字以避免所有陷阱。 ((如果浮点数已存在于程序中,则将其转换为string,或者简单地将浮点值读取为stringstream作为开头。

然后,只需要处理一个负值或以前导零开头的值(例如string)的情况,然后从原始浮点值复制(-31.3333)个数字即可转换为.push_back()之前,先将其转换为中间字符串。您可以使用.stoi(), .stol(), or .stoll()异常处理来处理任何失败的转换。

对于返回try {...} catch {...}值的函数,您可以执行以下操作:

long long

在一个简短的示例中将其放在一起,您可以:

#define LONGDIGITS 19

long long sdigits (std::string s)
{
    int start = 0;                          /* flag skip leading 0 */
    size_t n = 0, maxdigits = LONGDIGITS;   /* set max digits */
    long long l = 0;                        /* int to hold conversion */
    std::string result;                     /* string to hold digits */

    if (s[0] == '-') {              /* if leading '-' */
        result.push_back ('-');     /* save for sign */
        maxdigits++;                /* increment max by 1 */
    }
    for (auto c : s) {              /* loop over all chars */
        if (isdigit (c)) {          /* if not digit skip */
            if (c != '0')           /* if not 0, the set start flag */
                start = 1;
            if (start) {                /* if start set */
                result.push_back (c);   /* add digit to result */
                n++;                    /* increment digit count */
            }
        }
        if (n == maxdigits)         /* if digit count == max */
            break;                  /* break */
    }
    try {                           /* try conversion to long long */
        l = std::stoll (result);
    }
    catch ( std::exception& e ) {   /* catch/handle exception */
        std::cerr << "error: std::" << e.what() << " out_of_range.\n";
    }

    return l;   /* return long long value, or 0 on error */
}

执行此操作的方法可能有很多种,因此请不要将其作为唯一方法,但是您可以准确地处理转换并进行验证,从而确定任何失败。

使用/输出示例

#include <iostream>
#include <string>
#include <limits>
#include <cctype>

#define LONGDIGITS 19

long long sdigits (std::string s)
{
    int start = 0;                          /* flag skip leading 0 */
    size_t n = 0, maxdigits = LONGDIGITS;   /* set max digits */
    long long l = 0;                        /* int to hold conversion */
    std::string result;                     /* string to hold digits */

    if (s[0] == '-') {              /* if leading '-' */
        result.push_back ('-');     /* save for sign */
        maxdigits++;                /* increment max by 1 */
    }
    for (auto c : s) {              /* loop over all chars */
        if (isdigit (c)) {          /* if not digit skip */
            if (c != '0')           /* if not 0, the set start flag */
                start = 1;
            if (start) {                /* if start set */
                result.push_back (c);   /* add digit to result */
                n++;                    /* increment digit count */
            }
        }
        if (n == maxdigits)         /* if digit count == max */
            break;                  /* break */
    }
    try {                           /* try conversion to long long */
        l = std::stoll (result);
    }
    catch ( std::exception& e ) {   /* catch/handle exception */
        std::cerr << "error: std::" << e.what() << " out_of_range.\n";
    }

    return l;   /* return long long value, or 0 on error */
}

int main (void) {

    std::string s;
    long long l;

    std::cout << "enter double in range of 64-bit int: ";
    if (!(std::cin >> s)) {
        std::cerr << "err: invalid input.\n";
        return 1;
    }

    l = sdigits (s);

    std::cout << s << " -> " << l << '\n';
}

负值也可以正确处理:

$ ./bin/double_all_digits
enter double in range of 64-bit int: 0.9332
0.9332 -> 9332

$ ./bin/double_all_digits
enter double in range of 64-bit int: 1.32001
1.32001 -> 132001

通过使用字符串进行中间解析,可以避免浮点重复十进制问题:

$ ./bin/double_all_digits
enter double in range of 64-bit int: -0.9332
-0.9332 -> -9332

通过使用$ ./bin/double_all_digits enter double in range of 64-bit int: 9.999999 9.999999 -> 9999999 $ ./bin/double_all_digits enter double in range of 64-bit int: -31.3333 -31.3333 -> -313333 异常处理,您可以捕获任何try {...} catch {...}转换。到out_of_range的最大允许转换为:

long long

同时添加一个将导致$ ./bin/double_all_digits enter double in range of 64-bit int: 0.9223372036854775807 0.9223372036854775807 -> 9223372036854775807 的值超出范围:

long long

答案 2 :(得分:0)

您可以使用C ++标准库字符串函数将浮点数字转换为整数。

#include <iostream>
#include <string>
#include <cctype>

int floatDigitToInt(float num) {
    std::string str_f = std::to_string(num);
    // here one can check NaN, inf etc..
    std::string str_i;
    for (int i = 0; i < str_f.length(); ++i) {
        if (std::isdigit(str_f[i])) {
            str_i += str_f[i];
        }
    }
    return std::stoi(str_i);
}

int main() {
    float num_f = 1.32001;
    std::cout << floatDigitToInt(num_f);
    return 0;
}

答案 3 :(得分:0)

您不必要地将自己画在一个角落。如果您需要以正确的十进制浮点数表示结果,则应使用dec64之类的十进制浮点数进行计算,而不要尝试使错误的结果恢复正常。

答案 4 :(得分:0)

  

如何将双精度或浮点数(所有数字)转换为整数?

0.9332  --> 9332  
1.32001 --> 132001

通常不可能严格实现目标。
Typically,大约有2 64 个不同的double0.93321.32001不在double的集合中。


让我们看看最接近的替代品。

最接近的double的精确值为 ,如下所示。某些double,例如 binary 浮点值需要100的十进制数字来表示。

0.933200000000000029487523534...
1.32000999999999990563992469...

要合理地将这些值“打印为int”,我们需要选择所需的精度。

假设我们选择小数点后的固定位数。 (对于小的double值,因为它们全部变为“ 0”并不是一个好主意),代码可以根据需要对字符串进行后处理。

int len = snprintf(NULL, n, "%.*f", 16, double_value);
char buf(len + 1];
snprintf(buf, sizeof buf, "%.*f", 16, double_value);
char *dp = strchr(buf, '.');  // Look for the decimal point - might be `,` in some locales
if (dp) {
  size_t len = strlen(dp + 1);
  memmove(dp, dp + 1, len + 1); // shove over fraction
  while (len > 0 && dp[len - 1] == '0') {
    dp[--len] = '\0';  // lop off trailing zeros.
  }
} 

现在buf[]仅包含适用于strto...()转换为某种整数类型(如果“适合”)的数字(除非无穷/ NaN)。 buf[]可能包含数百个数字,因为DBL_MAX通常约为3.0e308左右。 OP的目标并未针对非常大的double来表示。


在有限的double范围内,代码使用"%.*g",其中“从结果的小数部分删除尾随零”,然后post = proess处理字符串以删除{{1 }}。

'.'

输出

printf("%.16g\n", 0.9332);
printf("%.16g\n", 1.32001);