我在ifstream
的文件中读到了,我希望用cout
写出已读取的文件的百分比。
long length = 0, now = 0;
int i = 0;
double d = 0;
file.seekg( 0, std::ios::end );
length = file.teelg();
file.seekg( 0, std::ios::beg );
while ( std::getline( file, buffer ) ) {
now = file.teelg;
i = now / length * 100;
d = now / length * 100;
std::cout << length << " " // working
<< now << " " // working
<< ( now / length * 100 ) << " " // not working = 0
<< i << " " // not working = 0
<< d; // not working = 0
}
仅当now = length
向我显示它是100%
时,但每隔一次它失败并返回给我0
。
我可以想象,答案很简单,如1*1
,但现在我找不到解决方案。我也尝试过铸造,也许是因为这是问题所在,但当然没有。
答案 0 :(得分:6)
除非其中一个操作数是float
或double
,否则/
会进行整数除法并丢弃余数。
像这样写:
( (double)now / length * 100 )
答案 1 :(得分:6)
如果length > now
,那么now / length
在整数除法中为零。先投两双。
答案 2 :(得分:2)
将计算转换为浮动
i = (float)now / length * 100;
d = (float)now / length * 100;
基本上,如果你划分整数,则向下舍入到最接近的数字。因此,你只能有0或1.然后它乘以100.
或者,你可以这样做:
i = 100 * now / length;
d = 100 * now / length;
在数字乘以100后,这将向下舍入。
答案 3 :(得分:1)
试试(now * 100) / length
。
这是因为now / length
的结果转换为int,因此它可能只是0
或1
。
答案 4 :(得分:1)
或者,为避免浮动除法,您也可以先乘,然后除以:
(now * 100) / length
答案 5 :(得分:1)
你的表达
( now / length * 100 )
从左到右进行评估,因此像这样:
int tmp = now / length
int result = tmp * 100
因为......
5.6乘法运算符[expr.mul]
[...] 积分操作数/运算符产生代数商,丢弃任何小数部分[...]
...对于任何now < length
,结果将为零。
添加浮点转换可以提供帮助:
5表达式[expr] :
10 :许多期望算术或枚举类型操作数的二元运算符会导致转换和产生 结果类型以类似的方式。目的是产生一个通用类型,它也是结果的类型。 这种模式称为通常的算术转换,定义如下:
- ...
- 如果任一操作数的类型为long double,则另一个操作数应转换为long double。
- 否则,如果任一操作数为double,则另一个操作数应转换为double。
- 否则,如果任一操作数为float,则另一操作数应转换为float。
- ...
总而言之,对于任何两个原始操作数(或任何非重载operator/
),如果一个操作数是浮点类型,另一个操作数也会转换为浮点类型:
float(now) / length * 100
...会将所有操作数转换为float:
float tmp = float(now) / length
float result = tmp * 100.0f
但您也可以重新排列计算以不使用任何浮点数学:
i = 100*now / length;
d = 100*now / length
然后根据需要给出一个整数。
如果你想知道为什么这会以数学方式起作用:
100*now now
---------- = 100 * --------
length length
左边是你现在拥有的,右边是你拥有的。两者都是等价的,但是当涉及到有限的数据类型时,执行的顺序变得高度相关。