C++ 如何计算c+中双变量的小数位数+;?

C++ 如何计算c+中双变量的小数位数+;?,c++,floating-point,double,decimal,C++,Floating Point,Double,Decimal,在我大学的一门课程中,我需要编写一个程序,将数字转换成数字 自然语言,例如,如果用户输入“2.55”,程序输出“2.55”。 我马上就要完成了我唯一得不到的就是分数后面的数字。 我不允许使用字符串。下面是我如何获得小数位数的方法: i=0; while((wert - (long int)wert) != 0){ wert /= 10; i++; } 但它给出了示例数字“2.55”的356个小数位的值。有没有不使用字符串来计算小数位数的方法 致以最诚挚的问候由于浮点精度,您将无

在我大学的一门课程中,我需要编写一个程序,将数字转换成数字 自然语言,例如,如果用户输入“2.55”,程序输出“2.55”。 我马上就要完成了我唯一得不到的就是分数后面的数字。 我不允许使用字符串。下面是我如何获得小数位数的方法:

i=0;
while((wert - (long int)wert) != 0){
    wert /= 10;
    i++;
}
但它给出了示例数字“2.55”的356个小数位的值。有没有不使用字符串来计算小数位数的方法


致以最诚挚的问候

由于浮点精度,您将无法使用
双精度
来执行此操作。例如,设置为0.2的
double
的小数位数将比1多得多,因为0.2无法精确表示。(为什么不在调试器中检查
double
的实际值呢?)2.55也不能精确表示


在这里,最简单的方法可能是使用字符串表示数字,并将解析器建立在该数字的基础上。

由于浮点精度的原因,您将无法使用双精度。例如,设置为0.2的
double
的小数位数将比1多得多,因为0.2无法精确表示。(为什么不在调试器中检查
double
的实际值呢?)2.55也不能精确表示


在这里,最简单的方法可能是使用字符串表示数字,并将解析器建立在该数字的基础上。

您必须知道在该点之后必须支持的最大位数。比如说
n
最大位数。将数字的小数部分乘以
10^n
,然后将所得数字右移,直到最后一位与
0
不同,以删除尾随的零。然后逐个打印数字:

void printDigitsAfterPoint(double x) {
    int k = Math.round((x-(int) x)*Math.pow10(n));
    // remove trailing zeroes
    while (k!=0 && k%10==0) {
        k/=10;
    }
    // output digits
    while (k!=0) {
        output(k%10); // you already should have a method like this...
        k/=10;
    }
}
确保添加用于处理
x
负值的代码。我相信你的教授会试试


编辑:忘记更改声明。已修复。

您必须知道该点后必须支持的最大位数。比如说
n
最大位数。将数字的小数部分乘以
10^n
,然后将所得数字右移,直到最后一位与
0
不同,以删除尾随的零。然后逐个打印数字:

void printDigitsAfterPoint(double x) {
    int k = Math.round((x-(int) x)*Math.pow10(n));
    // remove trailing zeroes
    while (k!=0 && k%10==0) {
        k/=10;
    }
    // output digits
    while (k!=0) {
        output(k%10); // you already should have a method like this...
        k/=10;
    }
}
确保添加用于处理
x
负值的代码。我相信你的教授会试试


编辑:忘记更改声明。已修复。

如果用户正在输入数字,它将以字符串的形式输入,或者说是进入字节数组,因此根本不需要将浮点值带入其中。只需找到数据中的小数点,然后开始计算数字


注意:你标题中的问题毫无意义。浮点变量没有小数点,它们有二进制位,小数点和二进制位是不可通约的。如果你的教授想让你使用浮点,他自己需要。

如果用户正在输入数字,它将以字符串的形式输入,或者说是进入字节数组,因此根本不需要将浮点引入其中。只需找到数据中的小数点,然后开始计算数字


注意:你标题中的问题毫无意义。浮点变量没有小数点,它们有二进制位,小数点和二进制位是不可通约的。如果你的教授想让你使用浮点,他需要自己。

最接近2.55的IEEE 64位二进制数是2.5499999999998223643160599749535322183310546875,小数点后只有50位

重复的划分毫无意义。忽略舍入误差,
wert
的值将为2.55、0.255、0.0255、0.00255等。这些值都不等于任何长值。当
wert
下溢为零时,循环终止

相反,你应该乘以10。但是,如果保留前导数字,则可能会得到一个太大的数字,在获得相等值之前很长时间都无法存储。相反,我建议在每一步减去整数部分,当结果为零时停止


这仍然会导致一个50位小数的答案,但如果你的教授坚持使用双精度,那可能就是你想要的。

最接近2.55的IEEE 64位二进制数是2.5499999999982236431605999749535322183310546875,它在小数点后只有50位

char* fractpart(double f)
{
char chrstr[5];
char charary={'1','2','3',....,'0'};
int intary={1,2,3,...,0};
int count=0,x,y;
f=f-(int)f;
        while(f<=1)
        {
         f=f*10;
           for(y=0;y<10;y++)
           {
               if((int)f==intary[y])
               { 
               chrstr[count]=charary[y];
               break;
               }
           }
   f=f-(int)f;
      if(f<=0.01 || count==4)
      break;
      if(f<0)
      f=-f;
      count++;
}
     return(chrstr);
}
重复的划分毫无意义。忽略舍入误差,
wert
的值将为2.55、0.255、0.0255、0.00255等。这些值都不等于任何长值。当
wert
下溢为零时,循环终止

相反,你应该乘以10。但是,如果保留前导数字,则可能会得到一个太大的数字,在获得相等值之前很长时间都无法存储。相反,我建议在每一步减去整数部分,当结果为零时停止

这仍然会导致一个50位小数的答案,但如果你的教授坚持要双精度,也许这就是你想要的。

char*fractpart(双f)
char* fractpart(double f)
{
char chrstr[5];
char charary={'1','2','3',....,'0'};
int intary={1,2,3,...,0};
int count=0,x,y;
f=f-(int)f;
        while(f<=1)
        {
         f=f*10;
           for(y=0;y<10;y++)
           {
               if((int)f==intary[y])
               { 
               chrstr[count]=charary[y];
               break;
               }
           }
   f=f-(int)f;
      if(f<=0.01 || count==4)
      break;
      if(f<0)
      f=-f;
      count++;
}
     return(chrstr);
}
{ char-chrstr[5]; 字符={'1','2','3',..,'0'}; int intary={1,2,3,…,0}; 整数计数=0,x,y; f=f-(int)f; 而(f
char*fractpart(双f)
{
char-chrstr[5];
字符={'1','2','3',..,'0'};
int intary={1,2,3,…,0};
整数计数=0,x,y;
f=f-(int)f;

虽然(fFloating point不是这样工作的…很难预测像“2.55”这样的数字将如何存储为双精度-您可能会得到像“2.549999…”。选择一个固定精度并坚持它。与其与零进行精确比较,不如尝试检查零与数字之间的差值是否非常小。预期输入的数字范围是什么?它是64位系统的完整浮点范围吗?是否允许将输入解析为两个独立的整数?具体取决于