【问题标题】:c++ convert a fractional part of a number into integerc ++将数字的小数部分转换为整数
【发布时间】:2012-09-29 20:17:04
【问题描述】:

我需要将数字的小数部分转换为不带逗号的整数, 例如我有 3.35 我只想得到 35 部分没有零或逗号,

因为我使用了 modf() 函数来提取小数部分,但它给了我 0.35 如果有任何方法可以做到这一点或过滤“0”。如果您向我展示如何使用更小的代码,我将非常感激,

【问题讨论】:

  • 总是只有两位小数吗?乘以 100 并转换为整数怎么样?
  • 将其格式化为字符串,然后复制小数点后的所有内容,或删除第一个数字字符之前的所有内容。 (然后您可以将其转换回 int,如果这是您需要的)
  • 3.35的二进制表示很可能是3.349999986f左右。 3.350 的二进制表示是相同的。给定两个输入 3.35 和 3.350 ,您期望输出的具体内容是什么?
  • 请注意,doublefloat 类型不能精确表示 3.35,因为这是二进制的无限周期分数。您需要使用类似于建议的 decimal64 甚至 int 之类的类型,如果您想要准确的话,乘以 100
  • @MSalters 3.350000000000000088817841970012523233890533447265625 准确地说

标签: c++ math integer


【解决方案1】:

我刚刚做了一些接近你想要做的事情,虽然我还是个新手。尽管如此,当我来到这里寻找我的问题的结果时,也许这将有助于将来的某人。

第一步是确保包含 3.35 的变量是双精度数,但这可能很明显。

接下来,创建一个仅为整数的变量并将其值设置为等于双精度值。然后它将只包含整数。

然后从双精度数中减去整数 (int)。您将留下分数/小数值。从那里,只需乘以 100。

超过 100 个十进制值,您显然需要进行更多配置,但使用 if 语句应该相当简单。如果十进制值大于 0.99,则乘以 1000,等等。

【讨论】:

    【解决方案2】:
    #include <iostream>
    #include <cmath>
    
    double round(double r) {
        return (r > 0.0) ? std::floor(r + 0.5) : std::ceil(r - 0.5);
    }
    
    double floor_to_zero(double f) {
        return (f > 0.0) ? std::floor(f) : std::ceil(f);
    }
    
    double sign(double s) {
        return (s < 0.0) ? -1.0 : 1.0;
    }
    
    int frac(double f, int prec) {
        return round((f - floor_to_zero(f)) * prec) * sign(f);
    }
    
    int main() {
        double a = 1.2345;
        double b = -34.567;
        std::cout << frac(a, 100) << " " << frac(b, 100) << std::endl; // 23 57
    }
    

    【讨论】:

      【解决方案3】:

      使用一些 stl 魔法,here is 示例代码:

      typedef std::pair<int, int> SplitFloat;
      
      SplitFloat Split(float value, int precision)
      {
          // Get integer part.
          float left = std::floor(value);
          // Get decimal part.
          float right = (value - left) * float(std::pow(10, precision));
      
          return SplitFloat(left, right);
      }
      

      它可以改进,但非常简单。

      【讨论】:

        【解决方案4】:

        这样的事情应该可以工作:

        #include <stdio.h>
        #include <stdlib.h>
        #include <math.h>
        
        static int get_frac(double value, unsigned short precision)
        {
            return (int)((value - (long)value) * pow(10, precision));
        }
        
        static int get_frac_no_trailing_zeros(double value, unsigned short precision)
        {
            int v = get_frac(value, precision);
            while (v % 10 == 0)
                v /= 10;
            return v;
        }
        
        int main(int argc, char *argv[])
        {
            double v;
        
            v = 123.4564;
            printf("%.4f = %d\n", v, get_frac(v, 2));
            printf("%.4f = %d\n", v, get_frac(v, 4));
            printf("%.4f = %d\n", v, get_frac(v, 6));
            printf("%.4f = %d\n", v, get_frac_no_trailing_zeros(v, 6));
        
            return EXIT_SUCCESS;
        }
        

        您可能还想避免调用pow,首先让用户提供一个 10 的幂的数字,或者使用查找表。

        【讨论】:

          【解决方案5】:

          如果您需要它作为字符串,一个非常简单的 C 风格解决方案将是(应该适用于可变的小数位数):

              double yourNumber = 0.35f;
              char buffer[32];
              snprintf(buffer, 32, "%g", yourNumber);
              strtok(buffer, "."); // Here we would get the part before . , should still check
              char* fraction = strtok(NULL, ".");
              int fractionAsInt = atoi(fraction);
          

          这个例子在错误字符串的情况下缺乏错误处理,如果你只需要固定的小数位数,这个例子是不可行的,因为算术方法在那里工作得更好。

          【讨论】:

            【解决方案6】:

            比转换成字符串再返回效率高一点:

            int fractional_part_as_int(double number, int number_of_decimal_places) {
                double dummy;
                double frac = modf(number,&dummy);
                return round(frac*pow(10,number_of_decimal_places));
            }
            

            【讨论】:

              【解决方案7】:

              另一种解决方案

              int precision= 100;
              double number = 3.35;
              int f = floor(xx);
              double temp = ( f - number ) * -1;
              int fractional_part = temp * precision;
              

              【讨论】:

              • number - f 代替( f - number ) * -1 怎么样?
              • 这不适用于负数。 -0.1 给出 90
              【解决方案8】:

              我会这样做。

              #include <sstream>
              #include <string>
              
              int main()
              {
                  double d = yourDesiredNumber; //this is your number
                  std::ostringstream out;
                  out << setprecision(yourDesiredPrecision) << std::fixed 
                      << std::showpoint << d;
                  std::istringstream in(out.str());
                  std::string wholePart; //you won't need this. 
                  int fractionalPart;  
                  std::getline(in, wholePart, '.');
                  in >> fractionalPart;
                  //now fractionalPart contains your desired value.
              }
              

              我很确定不是两个不同的 istringstreamostringstream 对象,你可以只使用一个 stringstream 对象,但我不确定细节(从未使用过那个类)所以我在示例中没有使用它。

              【讨论】:

              • @RichardJ.RossIII:老实说,我在等你发布答案,看看会做什么。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-08-01
              • 2011-09-26
              • 2011-10-04
              • 1970-01-01
              相关资源
              最近更新 更多