Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#和Java之间表达式中浮点或双精度的隐式转换/提升_C#_Java - Fatal编程技术网

C#和Java之间表达式中浮点或双精度的隐式转换/提升

C#和Java之间表达式中浮点或双精度的隐式转换/提升,c#,java,C#,Java,如果我有以下表达式: byte A = 69; int B = 123; long C = 3210; float D = 4.9f; double E = 11.11; double X = (B * 100) + 338.1 - (E / B) / C; double X1 = (B * 100) + (A * D) - (E / B) / C; // JAVA - lost precision System.out.println(X); // 12638.099971861307

如果我有以下表达式:

byte A = 69;
int B = 123;
long C = 3210;
float D = 4.9f;
double E = 11.11;

double X = (B * 100) + 338.1 - (E / B) / C;
double X1 = (B * 100) + (A * D) - (E / B) / C;

// JAVA - lost precision
System.out.println(X);  // 12638.099971861307
System.out.println(X1); // 12638.099581236307

// C# - almost the same
Console.WriteLine(X);  // 12638.0999718613
Console.WriteLine(X1)  // 12638.0999784417
我注意到Java在X中失去了精度,其中338.1是隐式双精度的,而C几乎没有。我不明白为什么,因为338.1在float和double中是相等的。点后只有一个数字。

在Java中,
(B*100)+(A*D)
将是一个浮点数;最接近12638.1的浮动。然而,12638需要14位二进制数字,包括首字母1;留下10位有效位来表示小数部分。因此,您将得到与0.1最接近的1024个数字,即102/1024。结果是0.099609375-因此浮点的舍入误差为0.000390625

这似乎就是Java程序中X和X1之间的区别


恐怕我不是C语言专家,所以我无法告诉你为什么C语言不同。

这与编译器对表达式的解释有关。由于没有指定任何中间类型转换,编译器将执行
A*D
作为第一个类型转换,然后执行乘法,而不是预期的相反操作。这看起来可能是一个奇怪的结果,但编译器可以通过这种方式为您提供更精确的结果,而无需指定繁琐的类型转换

Java不会为您处理这个问题,因此
(B*100)+(A*D)
int
float
的乘积,从而产生
float
。这可以用C#进行模拟,如下所示:

double X2 = (float)((B * 100) + (A * D)) - (E / B) / C;
Console.WriteLine("X2: {0}", X2);

这是高级编译器的优点之一(或者有些人可能会说是缺点)。

338.1在float和double中是不同的。338.1的精确二进制扩展永远重复,因此当用双精度表示时,它的非零位数比用浮点表示时多得多。请阅读