Перевод кода с Паскаля на C# - C# (216535)
Формулировка задачи:
надеюсь кто-то из C# юзеров ещё помнят паскаль.
суть в том что я перебивал код с паскаля(работает правильно) на C#.вроде бы и перебил верно но результат неверный.что не так?неясно.
Матрицу вводится верно.(это метод Крамера если что)
перебивал максимально дословно.
и пример вот
матрица
2 0 -1
0 2 -1
-1 -1 0
свободные члены
-4 -8 -180
результат
89 91 180
uses crt;
type
Tmass=array[1..20] of real;
Tmatrix=array[1..20] of Tmass;
procedure Per(k,n:integer;var a:Tmatrix;var p:integer);{перестановка строк если главный элемент = 0}
var z:Real;j,i:integer;
begin
z:=abs(a[k,k]);
i:=k;
p:=0;
for j:=k+1 to n do
begin
if abs(a[j,k])>z then{выбираем максимальный по модулю в данном столбце ниже}
begin
z:=abs(a[j,k]);
i:=j;
p:=p+1;{счетчик перестановок, при каждой перестановке меняется знак определителя}
end;
end;
if i>k then
for j:=k to n do
begin
z:=a[i,j];
a[i,j]:=a[k,j];
a[k,j]:=z;
end;
end;
function Znak(p:integer):integer;{определение знака определителя}
begin
if p mod 2=0 then
Znak:=1 else Znak:=-1;
end;
procedure Opr(n:integer;a:tmatrix;var det:real);{вычисление опаределителя}
var k,i,j,p:integer;r:real;
begin
det:=1.0;
for k:=1 to n do
begin
if a[k,k]=0 then Per(k,n,a,p);{перестановка строк}
det:=znak(p)*det*a[k,k];{вычисление определителя}
for j:=k+1 to n do {пересчет коэффициентов}
begin
r:=a[j,k]/a[k,k];
for i:=k to n do
begin
a[j,i]:=a[j,i]-r*a[k,i];
end;
end;
end;
end;
var a:Tmatrix;{матрица коэффициентов исходная}
c:array[1..20] of Tmatrix;{вспомогательные матрицы для вычисления корней}
b,x:Tmass;{свободные члены, корни}
det,det1:real;{определители}
n,k,j,i:integer;
begin
clrscr;
write('Порядок системы n=');
readln(n);
writeln('Введите коэффициенты системы:');
for i:=1 to n do
for j:=1 to n do
read(a[i,j]);
readln;
writeln('Введите свободные члены:');
for i:=1 to n do
read(b[i]);
readln;
clrscr;
writeln('Расширенная матрица системы:');
for i:=1 to n do
begin
for j:=1 to n do
write(a[i,j]:7:2);
write(b[i]:9:2);
writeln;
end;
Opr(n,a,det);{определитель системы исходной}
for i:=1 to n do
begin
for k:=1 to n do
begin
for j:=1 to n do{создаем вспомогательные матрицы, где i-товый столбец - свободные члены}
c[i][k,j]:=a[k,j];
c[i][k,i]:=b[k];
end;
Opr(n,c[i],det1);{определитедь вспомогательной матрицы}
if(det=0)and(det1=0) then
begin
writeln('Система не определена!');
readln;
exit;
end;
if(det=0)and(det1<>0) then
begin
writeln('Система не имеет решений!');
readln;
exit;
end;
x[i]:=det1/det;{корень}
end;
writeln('Корни сиcтемы:');
for i:=1 to n do
writeln('x',i,'=',x[i]:7:3);
readln
end.using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TEmps
{
class Program
{
static void Perestanovki(int k, int n, double[][] a, ref int p)//перестановки
{
double z;
int i = k;
z = Math.Abs(a[k][k]);
p = 0;
for (int j = k + 1; j < n; j++)
{
if (Math.Abs(a[j][k]) > z)
{
z = Math.Abs(a[j][k]);
i = j;
p += 1;//счетчик перестановок для смены знака
}
}
if (i > k)
for (int j = k; j < n; j++)
{
z = a[i][j];
a[i][j] = a[k][j];
a[k][j] = z;
}
}
static int Znak(int p)//знак определителя
{
if (p % 2 == 0) return 1;
return -1;
}
static void Determinant(int n, double[][] a, ref double det)//поиск определителя
{
int p = 0;
det = 1.0;
for (int k = 0; k < n; k++)
{
if (a[k][k] == 0) Perestanovki(k, n, a, ref p);//перемтановка строк
det = Znak(p) * det * a[k][k];//вычисление определителя
for (int j = k + 1; j < n; j++)
{
double r = a[j][k] / a[k][k];
for (int i = k; i < n; i++)
a[j][i] = a[j][i] - r * a[k][i];
}
}
}
static double[] Mainpart(double[][] a, int n, double[] b)//основная часть программы
{
double det = 0;
double det1 = 0;
double[] x;
x = new double[n];
//массив определителей
double[][][] c;
c = new double[n][][];
for (int i = 0; i < n; i++)
c[i] = new double[n][];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
c[i][j] = new double[n];
Determinant(n, a, ref det);//определитель исходной системы
for (int i = 0; i < n; i++)//вспомогательные матрицы
{
for (int k = 0; k < n; k++)
{
for (int j = 0; j < n; j++)
c[i][k][j] = a[k][j];
c[i][k][i] = b[k];
}
Determinant(n, c[i], ref det1);
if (det == 0 && det1 == 0)//не определена
{
//double[] x;
//x = new double[n];
for (int q = 0; q < n; q++)
x[q] = 1;
return x;
}
if (det == 0 && det1 != 0)//нет решений
{
//double[] x;
//x = new double[n];
for (int q = 0; q < n; q++)
x[q] = 0;
return x;
}
x[i] = det1 / det;
}
return x;
}
static void Main(string[] args)
{
double[][] assert;
double[] x;
assert = new double[3][];
for (int i = 0; i < 3; i++)
assert[i] = new double[3];
Console.WriteLine("Бесплатники");
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
assert[i][j] = Double.Parse(Console.ReadLine());
double[] teta;
teta = new double[3];
Console.WriteLine("Свободники");
for (int i = 0; i < 3; i++)
teta[i] = Double.Parse(Console.ReadLine());
Console.WriteLine("Начальная матрица");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
Console.Write("{0} ", assert[i][j]);
Console.WriteLine("{0} ", teta[i]);
}
x = Mainpart(assert, 3, teta);
for (int i = 0; i < x.Length; i++)
Console.WriteLine("{0}", x[i]);
Console.ReadKey();
}
}
}
Есть идеи?
Решение задачи: «Перевод кода с Паскаля на C#»
textual
Листинг программы
procedure Opr(n:integer;a:tmatrix;var det:real);{вычисление опаределителя}
procedure Per(k,n:integer;var a:Tmatrix;var p:integer);{перестановка строк если главный элемент = 0}