所以浮点运算是不精确的,但这并不能完全解释这里发生的事情:
[46] pry(main)> a=0.05
=> 0.05
[47] pry(main)> a=a*26.0/65
=> 0.02
[48] pry(main)> a=0.05
=> 0.05
[49] pry(main)> a*=26.0/65
=> 0.020000000000000004
[50] pry(main)> 26.0/65
=> 0.4
浮点格式的意义有足够的位来表示26/65是不正确的。(“意义”是首选术语。意义是线性的。尾数是对数的。)
二进制浮点数的意义是二进制整数。这个整数是根据指数缩放的。为了用二进制浮点表示26/65,也就是。4,我们必须将它表示为一个整数乘以2的次方。例如,.4的近似值是1•2-1=0.5。一个更好的近似是3•2-3=.375。更好的是26•2-4=.40625。
然而,无论你用什么整数来表示意义或用什么指数,这种格式都不可能是精确的。假设您有。4=f•2e,其中f和e是整数。然后2/5=F•2E,SO2/(5F)=2E,然后1/(5F)=2E-1和5F=21-E。若要做到这一点,5必须是2的次方。不是,所以不能有。4=F•2E。
在IEEE-754 64位二进制浮点中,意义有53位。这样,与.4最接近的可表示值是0.400000000000000000002220446049250313080847263336181640625,等于3602879701896397•2-53。
现在让我们看看你们的计算。在a=0.05
中,0.05
转换为浮点值,生成0.05000000000000000000277555756156289135105907917022705078125。
在A*26.0/65
中,首先计算A*26.0
。精确的数学结果四舍五入到最接近的可表示值,产生1.30000000000000000000444089209850062616169452667236328125。然后这个除以65。同样,答案四舍五入,产生0.02000000000000000000004163336342344337026588618755340576171875。当Ruby打印这个值时,它显然决定它足够接近0.02,所以它只能显示“.02”,而不能显示完整的值。这是合理的,因为如果您将打印值。02转换回浮点,您将再次得到实际值,0.020000000000000000004163336342344337026588618755340576171875。所以“.02”在某种意义上是0.02000000000000000000004163336342344337026588618755340576171875的一个很好的代表。
在另一个表达式中,a*=26.0/65
。其中,首先计算26.0/65
。这产生0.400000000000000000002220446049250313080847263336181640625。这与第一个表达式不同,因为您以不同的顺序执行了操作,因此舍入了不同的数字。第一个表达式中的一个值可能是向下舍入的,而这个不同的值,因为它碰巧与浮点表示的值相对应,是向上舍入的。
然后该值乘以A
。这产生0.020000000000000000000388578058618804789148271083831787109375。注意,这个值比第一个表达式的结果离.02更远。您的Ruby实现知道这一点,因此它决定打印“.02”不足以准确地表示它。相反,它显示更多的数字,显示0.020000000000000004。
我有以下代码: 这会导致错误: 但是,在以下情况下(其中三元表达式中的括号已被删除): 没有错误,欢迎消息显示正确。 为什么会这样呢?在我的印象中,括号在三元表达式中是可选的。我认为这与求值的顺序有关,但是由于三元表达式在不同的行上,所以< code>let person = {...,我不清楚为什么会发生这种情况。 事实上,在我正在学习的JavaScript课程中,教师展示了下面的例子,无论有没
问题内容: 遇到一个错误地使用 而不是 在其代码中的人,它没有显示为编译错误。 是因为 是相同的 ? 问题答案: 没有编译错误,因为它是有效的(尽管相当无用) 一元运算符 ,其使用方式与以下方式相同: Java语言规范中的相关部分是Unary Plus运算符+(第15.15.3节) 。它指定调用一元运算会导致操作数的一元数值提升(第5.6.1节)。这意味着: * 如果操作数是编译时类型的,,,或,
问题内容: 在回答了这个问题之后,我很困惑为什么这段代码中的整数溢出而不是负数。奇怪,为什么这么精确的数字?为什么是0? 输出: 问题答案: 仅当的起始值为偶数时,才会发生这种情况。 根据JLS§15.17.1: 如果整数乘法溢出,则结果是数学乘积 的低阶位 ,以某种足够大的二进制补码格式表示。结果,如果发生溢出,则结果的符号可能与两个操作数值的数学积的符号不同。 如果我们以二进制格式而不是十进制
当我跑的时候 我在Java中得到错误。为什么?这相当于false==false,这是真的。这不是Java特有的,我在其他语言中也得到了相同的结果。这是因为短路评估吗?似乎左右双方仍会/应该进行比较。
当我发现这个奇怪的东西时,我正在玩JSX。使用以下JSX: 会产生正确的结果: 但我想在引号周围添加双引号,因此我尝试: 令我惊讶的是,它给出了正确的输出: 我希望得到类似的输出,因为它是字符串文字: 既然在字符串文本中,它为什么不按字面意思告诉我?这是巴贝尔的错误吗? 注意:这是一个自我提问和回答
我正在使用Java8。 预期输出为3。