C++ 如何计算c+中双变量的小数位数+;?
在我大学的一门课程中,我需要编写一个程序,将数字转换成数字 自然语言,例如,如果用户输入“2.55”,程序输出“2.55”。 我马上就要完成了我唯一得不到的就是分数后面的数字。 我不允许使用字符串。下面是我如何获得小数位数的方法: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个小数位的值。有没有不使用字符串来计算小数位数的方法 致以最诚挚的问候由于浮点精度,您将无
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;
而(fchar*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位系统的完整浮点范围吗?是否允许将输入解析为两个独立的整数?具体取决于