Короткие примеры C++ кода-1 Кувшинов Д



Download 326,03 Kb.
bet12/23
Sana21.03.2020
Hajmi326,03 Kb.
#42712
1   ...   8   9   10   11   12   13   14   15   ...   23
Bog'liq
Короткие примеры C

using namespace std;
// Корректность

void test_isqrt()

{

for (uint32_t n = 0;; ++n)

{

const auto

fpu = isqrt_fpu(n),

dt1 = isqrt_dt1(n),

dt2 = isqrt_dt2(n);



if (dt1 != fpu)

cout << "dt1 " << n << endl;

if (dt2 != fpu)

cout << "dt2 " << n << endl;

if (n == UINT32_MAX)

return;

}

}
// Время

#define TIME_TEST(func)\

double time_##func(unsigned dummy)\

{\

const auto t0 = clock();\

for (uint32_t n = 0; func(n) != dummy && n != UINT32_MAX; ++n) {}\

return double(clock() - t0) / CLOCKS_PER_SEC;\

}
TIME_TEST(isqrt_fpu)

TIME_TEST(isqrt_dt1)

TIME_TEST(isqrt_dt2)
void time_all(const char *msg, int dummy)

{

cout << msg;

cout << "\nfpu: " << time_isqrt_fpu(dummy) << "s\n";

cout << "dt1: " << time_isqrt_dt1(dummy) << "s\n";

cout << "dt2: " << time_isqrt_dt2(dummy) << "s\n\n";

}
int main()

{

test_isqrt();

cout << "Correctness testing done." << endl;

time_all("Full uint32_t range:", 65536);

time_all("First 1/64 of uint32_t range:", 8192);

time_all("First 1/256 of uint32_t range:", 4096);

time_all("First 1/4096 of uint32_t range:", 1024);

cout << "Time testing done." << endl;

//cin.ignore();

return EXIT_SUCCESS;

}

0650-polynomials_estrin2.cpp

// polynomials_estrin2.cpp

// Вычисление многочленов.

#include

#include

#include

#include

using namespace std;
/// близость значений по абсолютной разности

bool abs_close(double a, double b, double tol = 1e-10)

{

return abs(a - b) <= tol;

}
// многочлены
// sum(ai*x^i, i=0:(n-1)) = (...((a(n-1)*x + a(n-2))*x + ...)*x + a0

double poly_horner(double x, double a[], size_t n)

{

assert(n != 0);

auto s = a[--n];

while (n != 0)

s = s * x + a[--n];

return s;

}
// fma(a, b, c) --> (a * b + c) с одним округлением (C99, C++11)

double poly_horner_fma(double x, double a[], size_t n)

{

assert(n != 0);

auto s = a[--n];

while (n != 0)

s = fma(s, x, a[--n]);

return s;

}
// a3*x^3 + a2*x^2 + a1*x + a0 = (a3*x + a2)*x^2 + (a1*x + a0)

// sum(ai*x^i, i=0:(n-1)) =

// (...((a(n-1)*x + a(n-2))*x^2 + (a(n-3)*x + a(n-4)))*x^2 + ...)*x^2 + (a1*x + a0)

// -- метод Горнера по x^2

double poly_estrin2_fma(double x, double a[], size_t n)

{

assert(n != 0);

if (n == 1)

return a[0];
// один шаг схемы Эстрина + метод Горнера + fma

const auto x2 = x * x;

auto s = fma(a[n-1], x, a[n-2]);

for (--n; n > 2; n -= 2)

{

const auto p = fma(a[n-2], x, a[n-3]);

s = fma(s, x2, p);

}
// если был нечётный размер массива, то n == 2, иначе 1

return n != 2? s: fma(s, x, a[0]);

}

///////////////////////////////////////////////////////////////////////////////

// Тестирование
typedef double (*poly_eval_fun)(double, double*, size_t);

bool test_poly_eval(poly_eval_fun poly)

{

double test[] = { 20., -1., 4., 9., -8., 4. };

const size_t size = sizeof(test) / sizeof(double);

return poly(100., test, 1) == 20.

&& poly(0., test, size) == 20.

&& poly(0., test, size - 1) == 20.
&& abs_close(poly(1., test, size - 1), 24.)

&& abs_close(poly(-1., test, size - 1), 8.)

&& abs_close(poly(2.5, test, size - 1), -129.375)
&& abs_close(poly(1., test, size), 28.)

&& abs_close(poly(-1., test, size), 4.)

&& abs_close(poly(2.5, test, size), 261.25);

}
int main()

{

using namespace std;

poly_eval_fun poly[] =

{

poly_horner,

poly_horner_fma,

poly_estrin2_fma

};
for (auto pf: poly)

cout << test_poly_eval(pf);

cout << endl;
return EXIT_SUCCESS;

}

0700-amatrix.hpp

// amatrix.hpp

// Общие задачи обслуживания динамических массивов, которые можно интерпретировать как матрицы.

// Работа на C++ в стиле C.

#ifndef AMATRIX_HPP_INCLUDED_AMA700

#define AMATRIX_HPP_INCLUDED_AMA700
// Используются упакованные двумерные массивы.

// Под "упакованным" понимается массив, все элементы которого расположены в памяти без разрывов.

// Таким образом, фактически двумерный массив является одномерным с особым режимом индексирования.

// Элемент с двумерным индексом (i, j) имеет одномерный индекс (i * cols + j),

// где cols -- количество столбцов (т.е. строки идут друг за другом в памяти).

#include // size_t

#include // calloc, realloc, free
/// Описание матрицы.

struct Matrix_info

{

double *data; ///< Указатель на массив элементов.

size_t rows, ///< Количество строк.

cols; ///< Размер строки (количество столбцов).

};

// Ключевое слово inline позволяет размещать определения функций

// непосредственно в заголовочном файле, что часто удобно, так как не требуется отдельный .cpp файл.
/// Определить количество элементов матрицы mtx.

inline size_t matrix_size(const Matrix_info *mtx)

{

return mtx->rows * mtx->cols;

}
/// Создать динамический массив нужного размера, заполнить поля mtx.

/// Возвращает true в случае успеха и false в случае ошибки.

/// В случае ошибки выделения памяти обнуляет поля *mtx.

inline bool alloc_matrix(Matrix_info *mtx, size_t rows, size_t cols)

{

// Проверить, представимо ли произведение rows на cols в виде значения size_t.

const auto elements = rows * cols;

if (elements / rows == cols &&

(mtx->data = (double*)std::calloc(elements, sizeof(double))))

{

mtx->rows = rows;

mtx->cols = cols;

return true;

}

else

{

mtx->data = nullptr;

mtx->rows = 0;

mtx->cols = 0;

return false;

}

}
/// Освободить динамический массив, привязанный к матрице.

/// Обнуляет поля *mtx.

inline void free_matrix(Matrix_info *mtx)

{

std::free(mtx->data);

mtx->data = nullptr;

mtx->rows = 0;

mtx->cols = 0;

}
/// Переформатировать существующую матрицу под новый размер.

/// Возвращает true в случае успеха и false в случае ошибки.

/// В случае ошибки выделения памяти оставляет поля *mtx неизменными.

inline bool realloc_matrix(Matrix_info *mtx, size_t rows, size_t cols)

{

const auto elements = rows * cols;

// Проверить, представимо ли произведение rows на cols в виде значения size_t.

if (elements / rows != cols)

return false;
if (matrix_size(mtx) < elements)

{

const auto bytes = elements * sizeof(double);

if (bytes / sizeof(double) != elements)

return false; // Столько байт нельзя выделить.
// Попытаться расширить блок.

const auto data = (double*)std::realloc(mtx->data, bytes);

if (!data)

return false;
// Удалось расширить блок.

mtx->data = data;

mtx->rows = rows;

mtx->cols = cols;

return true;

}

else

{

mtx->rows = rows;

mtx->cols = cols;

return true;

}

}
/// Присвоить всем элементам матрицы заданное значение.

inline void fill_matrix(Matrix_info *mtx, double value)

{

const auto elements = matrix_size(mtx);

const auto data = mtx->data;

for (size_t i = 0; i < elements; ++i)

data[i] = value;

}
/// Заполнить матрицу значениями из статического массива (если требуется, выделяет память).

/// Значения полей *mtx должны быть инициализированы (хотя бы нулями).

inline void matrix_from_array(Matrix_info *mtx, size_t rows, size_t cols, const double *arr2)

{

// Подготовить место.

realloc_matrix(mtx, rows, cols);

// Скопировать поэлементно подряд.

const auto sz = matrix_size(mtx);

const auto data = mtx->data;

for (size_t i = 0; i < sz; ++i)

data[i] = arr2[i]; // вместо цикла можно использовать memcpy из cstring

}
/// Создать единичную матрицу размера n x n.

/// Значения полей *mtx должны быть инициализированы (хотя бы нулями).

inline void identity(Matrix_info *mtx, size_t n)

{

// Подготовить место.

realloc_matrix(mtx, n, n);

// Большинство элементов единичной матрицы -- нули.

fill_matrix(mtx, 0.0);

// Но по диагонали идут единицы.

auto write_pos = mtx->data;

for (size_t i = 0; i < n; ++i)

{

*write_pos = 1.0;

write_pos += (n + 1);

}

}
/// Скопировать содержимое одной матрицы в другую.

/// Значения полей *dst должны быть инициализированы (хотя бы нулями).

inline void copy_matrix(const Matrix_info *src, Matrix_info *dst)

{

// Подготовить место под копию.

realloc_matrix(dst, src->rows, src->cols);

// Скопировать всё содержимое массива подряд.

const auto elements = matrix_size(src);

const auto sd = src->data;

const auto dd = dst->data;

for (size_t i = 0; i < elements; ++i)

dd[i] = sd[i];

}
/// Сравнить матрицы на равенство.

inline bool matrices_are_equal(const Matrix_info *a, const Matrix_info *b)

{

// Если размеры матриц не равны, то и матрицы не равны.

if (a->rows != b->rows || a->cols != b->cols)

return false;
// Размеры совпали, сравним поэлементно.

const auto elements = matrix_size(a);

auto ad = a->data, bd = b->data;

for (size_t i = 0; i < elements; ++i)

if (ad[i] != bd[i])

return false;
// Равны поэлементно => равны.


Download 326,03 Kb.

Do'stlaringiz bilan baham:
1   ...   8   9   10   11   12   13   14   15   ...   23




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish