【问题标题】:How to convert float to int removing decimal point?如何将 float 转换为 int 去除小数点?
【发布时间】:2021-07-05 02:30:30
【问题描述】:

我想将 float 转换为 int 去除小数点,这意味着 如果 F = 2.521,则转换为 int = 2521 使用 C++ 快速执行此操作的方法是什么?

【问题讨论】:

  • round(F * 1000.0)。注意 float F = 2.521;F 不是完全 2.521。
  • 使用字符串。对于大部分浮点数,它们无法准确表示:stackoverflow.com/questions/588004/…
  • 除了上面 chux 所说的,舍入模式是:std::ceil、std::floor、std::trunc 或 std::round。圆形是最常见的,但可能不是您所需要的。
  • 这些花车的来源是什么? 2.5 是否应该映射到 252.52 映射到 252?如果是这样,您可能会遇到一些精度问题,即以十进制没有具有简短精确表示的事物在二进制中具有一个。
  • @G.Azma:您的意思是“不超过 8 个小数位”(例如 123456789123456789.0 变为 123456789123456789)还是“不超过 8 个有效数字(例如 123456789123456789.0 变为 12346)?前者可能会导致结果整数溢出问题。

标签: c++ performance type-conversion


【解决方案1】:

我不知道它是否是最快的方式(或者仅仅是“一种方式”),并且没有测试它是否按照我的意图运行(特别是在精度损失方面),但这是我尝试“提取到从浮点数到整数的 8 位有效十进制数字,尾随零抑制和向零舍入"):

#include <math.h>

int32_t convert(float value) {
    double v = value;     // Need to increase size to reduce risk of precision loss
    int sign = 0;
    int32_t result = 0;
    int digit;

    // Extract sign and ensure v isn't negative

    if(v < 0) {
        sign = 1;
        v = -v;
    }

    // Reduce magnitude of v by dividing by 10 until it's between 0.0 and 1.0 (exclusive).

    while(v >= 100000000.0) {
         v /= 1000000000.0;
    }
    if(v >= 10000.0) {
         v /= 100000.0;
    }
    if(v >= 100.0) {
         v /= 1000.0;
    }
    if(v >= 10.0) {
         v /= 100.0;
    } else if(v >= 1.0) {
         v /= 10.0;
    }

    // Extract (up to) 8 significant digits from v while trying to avoid trailing zeros (e.g. the original value 1.2 would hopefully become 12 and not 12000000).

    for(int i = 0; (i < 8) && ((float)v > 0.0); i++) {
        digit = floor(v * 10);
        result = result*10 + digit;
        v = v * 10 - digit;
    }

    // Suppress any trailing zeros that slipped through due to precision losses

    while( (result != 0) && (result % 10 == 0) ) {
        result /= 10;
    }

    // Restore the original value's sign

    if(sign != 0) {
         result = -result;
    }

    // Done!

    return result;
}

【讨论】:

    【解决方案2】:

    我用浮点数的字符串输入做到了这一点。将字符串字符放入整数数组中,除了“。”然后将整数数组转换为以 10 为底的十进制数。

    #include <iostream>
    #include <string>
    #include <math.h>
    using namespace std;
    int main()
    {
        string str="";
        cout<<"Enter num ?\n";
        cin>>str;
        int k = str.length()-1;
        int *a  = new int[k];
        int x=0;
        for(int i=0;i<str.length();i++)
        {
            if(str[i]!='.')
            a[x++] = (int(str[i]))-48;
            
        }
        long int res=0;
        x=0;
        for(int i=0;i<k;i++)
        {
            res+=a[k-1-i]*pow(10,x++);
        }
        cout<<"Integer is = "<<res<<endl;
    }
    

    【讨论】:

    • int *a = new int[k] 而不是 std::vector,也不是 delete[] - 这并不是 21 世纪 C++ 的一个很好的例子。
    【解决方案3】:
    for (; std::trunc(f) != f; f *= 10);
    std::intmax_t const i(f);
    

    请注意,可能仍然存在 UB,因为浮点数的范围非常大,您显然需要有符号整数类型。请注意,浮点数通常不是十进制的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-02
      • 1970-01-01
      • 1970-01-01
      • 2013-12-16
      • 2016-08-19
      • 2019-12-04
      • 2012-05-05
      相关资源
      最近更新 更多