几天前,当我使用C ++编程时,我犯了这个错误(我有这样做的历史!)。在我的代码的一部分中,我的值为1/6,我期望为0.16666666666,事实并非如此。众所周知,结果为0-C,C ++,Java,Python的行为均相同。
我将其发布在我的Facebook页面上,现在就是否存在1/6
与行为相同的编程语言存在争议1.0/6.0
。
1/6
中,实际上是1/6(小数类型),被强制Double
为1.66666 ...
几天前,当我使用C ++编程时,我犯了这个错误(我有这样做的历史!)。在我的代码的一部分中,我的值为1/6,我期望为0.16666666666,事实并非如此。众所周知,结果为0-C,C ++,Java,Python的行为均相同。
我将其发布在我的Facebook页面上,现在就是否存在1/6
与行为相同的编程语言存在争议1.0/6.0
。
1/6
中,实际上是1/6(小数类型),被强制Double
为1.66666 ...
Answers:
大家都忘了帕斯卡吗?
1/6
产量0.1666666...
(支持任何精度)。
1 div 6
产量 0
C规则是否错误是有争议的。几乎所有C的算术运算符(其操作数为相同类型)都会产生相同类型的结果。为了保持一致性,有话要说。
此外,由于C主要针对系统级代码,因此大多数C程序根本不使用浮点数。一次,不小心将浮点代码添加到原本不需要的程序中可能是一个严重的问题。对于小型嵌入式系统来说,情况仍然可能如此,这也是C的主要目标。
在大多数C程序中,无论如何,截断整数除法可能就是您想要的。
如果1 / 6
在C中产生浮点结果,则:
double
可能看起来像自然的选择,但你可能会喜欢的额外的精度long double
)C 可以为两种除法提供单独的运算符,但是上面的第二点仍然适用:三种浮点类型中的哪一种将用于结果?而且由于可以很容易地在需要时进行浮点除法(对一个或两个操作数使用浮点常量,或者将一个或两个操作数都转换为浮点类型),因此显然不是'认为很重要。
在1974年的C手册版本(即K&R第一版出版的前四年)中,Ritchie甚至没有提到可能的混淆:
二进制/运算符表示除法。与乘法相同的类型注意事项适用
表示如果两个操作数均为int
或类型char
,则结果为类型int
。
是的,这对于某些C程序员,尤其是初学者来说,是一个混乱的根源-但是,由于C对新手非常友好,因此并未引起人们的注意。
1.666666...
,这显然是错误的。我la脚的借口是我写的Pascal测试程序印制了1.6666666666666667E-0001
JavaScript出自著名语言。1.0 / 6.0 = 1/6 = 0.16666666666666666。
我认为这并不奇怪。根据经验,如果一种语言区分整数和浮点数字类型,则将两个整数相除将产生一个截断的整数,而不是浮点数。如果不是这样,很可能它将默认为浮点运算。这应该是程序员的预期行为。
请记住,这里还有其他一些功能,例如已经提到的单独的整数除法运算符或隐式类型转换。
许多语言的((1/6)*6)
结果都是1,而不是0。例如PL / SQL,许多BASIC方言Lua。
偶然地,在所有这些语言中,1/6都会产生.166666667或0.16666666666667或类似的结果。我选择了((1/6)* 6)== 1变体以消除这些小的差异。
((1/6)*6)==1
变体来消除那些小的差异,但似乎我高估了某些人的数学技能。
是的,Perl做到了。一线
perl -e '$x=1/6;print "$x\n";'
结果为:
0.166666666666667
我相信PHP的工作方式相同。
编辑添加:我还认为,所1/6 == 1.0/6.0
讨论语言的弱类型是必要的(但不充分)条件。
在Squeak Smalltalk /
上,对整数创建Fraction对象。因此,尽管这与float除法不同,但仍(1/6)*6
返回1。
是的,我刚刚检查了TI-99 / 4A内置的TI BASIC。由于将所有数值表达式都视为浮点,因此除法运算也是浮点。
TI BASIC READY
>PRINT 1/6
.1666666667
>