Pau*_*ce. 12 c casting type-conversion
为什么这个显式演员的结果与隐式演员的结果不同?
#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
}
Run Code Online (Sandbox Code Playgroud)
如果我做d =(长)((b - a + c)/ c); 我也得到10.为什么双重赋值有所不同?
Jon*_*eet 16
我怀疑差异是从80位浮点值转换为长转换与从80位浮点值到64位浮点值的转换然后转换为长转换.
(80位出现的原因是,这是用于实际算术的典型精度,以及浮点寄存器的宽度.)
假设80位结果类似于10.999999999999999 - 从那里转换为长数10.但是,最接近的64位浮点值到80位值实际上是11.0,因此两阶段转换最终会产生11.
编辑:给这个更多的重量......
这是一个Java程序,它使用任意精度算法进行相同的计算.请注意,它将最接近0.1的double值转换为BigDecimal - 该值为0.1000000000000000055511151231257827021181583404541015625.(换句话说,无论如何,计算的确切结果不是 11.)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
这是结果:
10.9999999999999994448884876874217606030632
Run Code Online (Sandbox Code Playgroud)
换句话说,这对于大约40个十进制数字是正确的(超过64或80位浮点数可以处理的方式).
现在,让我们考虑这个数字在二进制文件中的含义.我没有任何工具可以轻松地进行转换,但我们再次使用Java来提供帮助.假设标准化数字,"10"部分最终使用三位(比11位= 1011少一位).留下60位尾数用于扩展精度(80位)和48位用于双精度(64位).
那么,每个精度中最接近11的数字是多少?再次,让我们使用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)));
}
}
Run Code Online (Sandbox Code Playgroud)
结果:
10.999999999999999999132638262011596452794037759304046630859375
10.999999999999996447286321199499070644378662109375
Run Code Online (Sandbox Code Playgroud)
所以,我们得到的三个数字是:
Correct value: 10.999999999999999444888487687421760603063...
11-2^(-60): 10.999999999999999999132638262011596452794037759304046630859375
11-2^(-48): 10.999999999999996447286321199499070644378662109375
Run Code Online (Sandbox Code Playgroud)
现在为每个精度计算出最接近正确值的值 - 为了扩展精度,它小于11.将每个值舍入为long,最后分别为10和11.
希望这足以说服怀疑者;)
| 归档时间: |
|
| 查看次数: |
1301 次 |
| 最近记录: |