C++ 计算小数点后的#个小数位数
我想计算浮点数的小数点后的小数位数。 当实数在二进制中没有表示形式时,问题显然会出现,如C++ 计算小数点后的#个小数位数,c++,double,C++,Double,我想计算浮点数的小数点后的小数位数。 当实数在二进制中没有表示形式时,问题显然会出现,如3.5689113 我想知道——例如,如果有人在源代码中写了这个实数——是否可能得到数字7,即小数点后的位数 例如,下面的简单代码不起作用: int main() { double num = 3.5689113; int count = 0; num = abs(num); num = num - int(num); while ( abs(num) >
3.5689113
我想知道——例如,如果有人在源代码中写了这个实数——是否可能得到数字7,即小数点后的位数
例如,下面的简单代码不起作用:
int main()
{
double num = 3.5689113;
int count = 0;
num = abs(num);
num = num - int(num);
while ( abs(num) >
0.0000001 )
{
num = num * 10;
count = count + 1;
num = num - int(num);
}
std::cout << count; //48
std::cin.ignore();
}
intmain()
{
双数=3.5689113;
整数计数=0;
num=abs(num);
num=num-int(num);
while(abs(num)>
0.0000001 )
{
num=num*10;
计数=计数+1;
num=num-int(num);
}
std::cout我建议将其转换为字符串,然后在其上循环,并计算到达句点后出现的字符数
bool passedRadix=false
int i=0;//用于计算小数
std::ostringstream strs;
strs当类似的东西不起作用时,你会尝试打印数字
我这样做了,我发现你有一些浮点数精度问题。
我把int
四舍五入改为ceil
四舍五入,效果很好
尝试将int
s放回原处,您将看到:)
编辑:一个比使用ceil
s更好的策略(它可能会产生相同的舍入问题)是将数字舍入到最接近的整数。您可以使用floor(myNumber+0.5)
这是修改后的代码
int main()
{
double num = 3.56891132326923333;
// Limit to 7 digits
num = floor(num*10000000 + 0.5)/10000000;
int count = 0;
num = abs(num);
num = num - floor(num+0.5);
while ( abs(num) >
0.0000001 )
{
cout << num << endl;
num = num * 10;
count = count + 1;
num = num - floor(num+0.5);
}
std::cout << count; //48
std::cin.ignore();
return 0;
}
intmain()
{
双数=3.5689113232692333;
//限制为7位
num=地板(num*10000000+0.5)/10000000;
整数计数=0;
num=abs(num);
num=num-地板(num+0.5);
while(abs(num)>
0.0000001 )
{
cout为了防止浮点近似引入的错误,请尽早将数字转换为整数,并使用它
double num = 3.5689113;
int count = 7; // a maximum of 7 places
num = abs(num);
int remainder = int(0.5 + 10000000 * (num - int(num)));
while ( remainder % 10 == 0 )
{
remainder = remainder / 10;
--count;
}
对于浮点类型T
,最多可以恢复std::numeric\u limits::digits10
位。因此,要确定最后一个非零小数位数的位置,您需要使用此值作为精度并格式化数字。要避免使用指数表示法输出,您需要将格式化标志设置为std::ios_base::fixed
和非小数位数:
std::ostringstream out;
int non_fraction(std::abs(value) < std::numeric_limits<double>::epsilon()
? 1: (1 + std::log(std::abs(value)) / std::log(10)));
out << std::setprecision(std::numeric_limits<double>::digits10 - non_fraction)
<< std::fixed
<< value;
std::ostringstream out;
int非整数分数(标准::绝对值)<标准::数值极限::ε()
1:(1+std::log(std::abs(值))/std::log(10));
为什么你的ε只有7位数?0.0000001…我用的是实数,它在小数点后的位数不超过7位数。为什么你的实数在小数点后的位数不超过7位数?@moing:因为我用的是外汇汇率,所以我把实数四舍五入到最大值的7位数。对我来说,更有趣的数字是3.1
所以,C++表达式“代码>(double)3.1 < /Cord>没有十进制数字的有限数量,尽管答案显然是1。你不是说你的Rayes只有7个数字吗?)是的,我最多相交7位数。你会告诉我我猜;)因为它违反了,特别是“总是引用一个重要链接中最相关的部分,以防目标站点无法访问或永久脱机。”@Oswald,最重要的部分是“打印你的数字”和“将int改为ceil”@Guillaume07嗯,你的例子真的很奇怪,数字不知从哪里冒出来。这就是最大的精度问题。为什么要解释非小数位数?非小数位数越多,需要编码的双精度位数就越少?总共只有std::numeric\u limits::digits10
数字。如果您将精度设置为n
并使用std::ios_base::fixed
将有n
小数位数。这意味着,如果有m
非小数位数,您将得到n+m
位数。如果n+m
大于digits10
,格式将开始显示实际值而不是四舍五入值的数字来填充这些数字。为什么不将std::abs(value)<1
替换为std::abs(value)
对于value=0.0003
,非分数=-2,所以std::numeric\u limits::digits10-非分数=17>15这是无关紧要的事?
std::ostringstream out;
int non_fraction(std::abs(value) < std::numeric_limits<double>::epsilon()
? 1: (1 + std::log(std::abs(value)) / std::log(10)));
out << std::setprecision(std::numeric_limits<double>::digits10 - non_fraction)
<< std::fixed
<< value;