Почему этот код возвращает разные значения? (С# и VB.NET)
Код VB.NET:
Module Module1
Sub Main()
Dim x, y As Single
x = 0 + (512 / 2 - 407) / 256 * 192 * -1
y = 0 + (512 / 2 - 474) / 256 * 192
Console.WriteLine(x.ToString + ": " + y.ToString)
Console.ReadLine()
End Sub
End Module
Возвращает: 113,25: -163,5
Код С#:
class Program
{
static void Main(string[] args)
{
float x, y;
x = 0 + (512 / 2 - 407) / 256 * 192 * -1;
y = 0 + (512 / 2 - 474) / 256 * 192;
Console.WriteLine(x + ": " + y);
Console.ReadLine();
}
}
возвращает 0: 0
Я не понимаю, буду признателен за объяснение.
Ответы
Ответ 1
С# /
выполняет целочисленное деление, обрезая дробную часть. VB.NET неявно переходит к Double
.
Чтобы выполнить деление с плавающей запятой, введите в тип с плавающей точкой:
static void Main(string[] args)
{
float x, y;
x = 0 + (512 / 2 - 407) / (float)256 * 192 * -1;
y = 0 + (512 / 2 - 474) / (float)256 * 192;
Console.WriteLine(x + ": " + y);
Console.ReadLine();
}
Ответ 2
Линии С#, такие как 0
и 512
, имеют тип int
. Любой int/int
(int, деленный на int) приводит к целочисленному делению, которое отбрасывает любой дробный остаток, теряя точность. Если вместо 512
вместо 0
и 512F
использовать float-литеры, например 0F
, то С# будет выполнять деление с плавающей запятой, которое сохранит дробную часть.
static void Main(string[] args)
{
float x, y;
x = 0F + (512F / 2F - 407F) / 256F * 192F * -1F;
y = 0F + (512F / 2F - 474F) / 256F * 192F;
Console.WriteLine(x + ": " + y);
Console.ReadLine();
}