为什么这是显式类型转换的结果,从暗的决定有什么不同? [英] Why is the result of this explicit cast different from the implicit one?

查看:93
本文介绍了为什么这是显式类型转换的结果,从暗的决定有什么不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是为什么显式转换从隐式单不同的结果?

Why is the result of this explicit cast different from the implicit one?

#include <stdio.h>

double  a;
double  b;
double  c;

long    d;

double    e;

int main() {
    a = 1.0;
    b = 2.0;
    c = .1;

    d = (b - a + c) / c;
    printf("%li\n", d);        //    10

    e = (b - a + c) / c;
    d = (long) e;
    printf("%li\n", d);        //    11
    }

如果我做D =(长)((B - A + C)/ C);我也得到10.为什么分配给双有所作为?

If I do d = (long) ((b - a + c) / c); I also get 10. Why does the assignment to a double make a difference?

推荐答案

我怀疑差为80位浮点值到64转换为长VS从80位浮点值转换位之一的然后的转换为long。

I suspect the difference is a conversion from an 80-bit floating point value to a long vs a conversion from an 80-bit floating point value to a 64-bit one and then a conversion to a long.

(其理由80位上来在所有的是,这是用于实际算术的典型$ P ​​$ pcision,和浮点寄存器的宽度。)

(The reason for 80 bits coming up at all is that that's a typical precision used for actual arithmetic, and the width of floating point registers.)

假设80位的结果是一样的东西10.999999999999999 - 从一个长收率10。然而,最近的64位浮点值到80位的值实际上是11.0转换,所以这两个阶段转换最终产生11。

Suppose the 80-bit result is something like 10.999999999999999 - the conversion from that to a long yields 10. However, the nearest 64-bit floating point value to the 80-bit value is actually 11.0, so the two-stage conversion ends up yielding 11.

编辑:为了给这多一点的重量...

To give this a bit more weight...

下面是它使用arbitrary- precision算术照此计算的Java程序。请注意,它最接近转换的双重价值0.1转换为BigDecimal - 该值0.1000000000000000055511151231257827021181583404541015625。 (换句话说,计算的精确结果的的11反正。)

Here's a Java program which uses arbitrary-precision arithmetic to do the same calculation. Note that it converts the double value closest to 0.1 into a BigDecimal - that value is 0.1000000000000000055511151231257827021181583404541015625. (In other words, the exact result of the calculation is not 11 anyway.)

import java.math.*;

public class Test
{
    public static void main(String[] args)
    {
        BigDecimal c = new BigDecimal(0.1d);        
        BigDecimal a = new BigDecimal(1d);
        BigDecimal b = new BigDecimal(2d);

        BigDecimal result = b.subtract(a)
                             .add(c)
                             .divide(c, 40, RoundingMode.FLOOR);
        System.out.println(result);
    }
}

下面是结果:

10.9999999999999994448884876874217606030632

在换句话说,这是正确的约40位十进制数字(超过方式更是64或80位浮点能处理)。

In other words, that's correct to about 40 decimal digits (way more than either 64 or 80 bit floating point can handle).

现在,让我们来考虑一下这个数字看起来像二进制文件。我没有任何工具可以轻松地进行转换,但我们可以再一次使用Java来帮助。假设一个标准化的号码,10的部分最终使用(小于十一年= 1011的)三位。这使得用于扩展precision尾数的60位(80位)和双precision 48位(64位)。

Now, let's consider what this number looks like in binary. I don't have any tools to easily do the conversion, but again we can use Java to help. Assuming a normalised number, the "10" part ends up using three bits (one less than for eleven = 1011). That leaves 60 bits of mantissa for extended precision (80 bits) and 48 bits for double precision (64 bits).

那么,什么是每个precision最接近数到11?同样,我们使用Java:

So, what's the closest number to 11 in each precision? Again, let's use Java:

import java.math.*;

public class Test
{
    public static void main(String[] args)
    {
        BigDecimal half = new BigDecimal("0.5");        
        BigDecimal eleven = new BigDecimal(11);

        System.out.println(eleven.subtract(half.pow(60)));
        System.out.println(eleven.subtract(half.pow(48)));        
    }
}

结果:

10.999999999999999999132638262011596452794037759304046630859375
10.999999999999996447286321199499070644378662109375

因此​​,我们已经拿到了三个数字是:

So, the three numbers we've got are:

Correct value: 10.999999999999999444888487687421760603063...
11-2^(-60): 10.999999999999999999132638262011596452794037759304046630859375
11-2^(-48): 10.999999999999996447286321199499070644378662109375

现在制定出最接近值,以正确为每个precision - 延长precision,它的每一个值小于11回合长了,你分别结束了10和11

Now work out the closest value to the correct one for each precision - for extended precision, it's less than 11. Round each of those values to a long, and you end up with 10 and 11 respectively.

希望这是足够的证据来说服持怀疑态度;)

Hopefully this is enough evidence to convince the doubters ;)

这篇关于为什么这是显式类型转换的结果,从暗的决定有什么不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆