Нашли или выдавили из себя код, который нельзя назвать нормальным,
на который без улыбки не взглянешь?
Не торопитесь его удалять или рефакторить, — запостите его на
говнокод.ру, посмеёмся вместе!
#include <iostream>
#include <conio.h>
#include <math.h>
using namespace std;
int main()
{
setlocale(0,"Russian");
cout<<"Пишиш без a,b,c,приклад: 2 5 -12 або натиснеш на Enter и пишеш вниз,"<<endl;
cout<<"ПИШИ:"<<endl;
float D;
int repetare=0;
int a;
int b;
int c;
int x1;
int x2;
repetare;
{
while(repetare<100)
{
cout<<"a=";
cin>>a;
cout<<"b=";
cin>>b;
cout<<"c=";
cin>>c;
D=(b^2-(4*a*c))*(-1);
x1=(b-sqrt(D))/(2*a);
x2=(b+sqrt(D))/(2*a);
if (D>0)
{
cout<<"D="<<D<<endl;
cout<<"x1="<<x1<<endl;
cout<<"x2="<<x2<<endl;
cout<<"Имеет два кореня"<<endl;
}
if (D<0)
{
cout<<"D="<<D<<endl;
cout<<"Не имеет кореней"<<endl;
}
if(D=0)
{
cout<<"D="<<D<<endl;
cout<<"x1="<<x1<<endl;
cout<<"Имеет один корень"<<endl;
}
repetare++;
}
}
getche();
return 0;
}
С одного из сайтов игроделов. Просто оставлю это здесь
Блин, я подобрал значения, на которых дискриминант правильно считается, и при этом является квадратом. Например a=1, b=5, c=4. Но уперся в другую траблу - тут в формулах для иксов вместо -b стоит просто b, поэтому ответ не сходится. b=0 брать нельзя, т.к. тогда a и c должны быть дробными. Что посоветуете сделать? 🙂
Попробовать подобрать такие значения, чтобы совпали иксы, насрав на некорректность дискриминанта? Но так не интересно ;(
Еще вариант приходит в голову - как-то сыграть на округлении к нулю, когда делят на 2*a.
Короче автор лабы мудак. Если бы он не обосрался в строках 29-30 с этим минусом, я бы показал контрольные примеры, на которых лаба все правильно считает 😉 А без минусов в 29-30 задача походу неразрешима.
Судя по данным, полученным в ходе эксперимента (если они верны),
1. Вероятность правильного решения с помощью этого кода падает с ростом (или ростом различия) a,b,c.
2. Вероятность получения правильного ответа для уравнения с 2 корнями крайне мала и скорее всего недостижима.
3. Для a,b,c из [-10; 10] решение работает правильно в 2% случаев.
Экспериментальная установка:
function result(D, x){
this.D = D;
this.x = x;
}
function lolSolve(a, b, c){
D=(b^2-(4*a*c))*(-1);
x1=(b-Math.sqrt(D))/(2*a) | 0;
x2=(b+Math.sqrt(D))/(2*a) | 0;
if (D>0) return new result(D, [x1, x2]);
if (D<0) return new result(D, []);
if (D=0) return new result(D, [x1]);
return new result(null);
}
var MIN = -10, MAX = 10;
var counter = 0;
for(var a = MIN; a <= MAX; ++a){
for(var b = MIN; b <= MAX; ++b){
for(var c = MIN; c <= MAX; ++c){
var r = lolSolve(a, b, c);
var D = b*b - 4*a*c;
if(r.D != D) continue;
if(r.x.every(function(x){ a*x*x + b*x + c === 0; })){
console.log('OK', a, b, c, '=>', r.D, r.x);
++counter;
}
}
}
}
console.log('success:', 100 * counter / Math.pow((MAX-MIN+1), 3), '%');
Некоторые результаты: OK -10 -2 -10 => -396 []
OK -10 -2 -9 => -356 []
OK -10 -2 -8 => -316 []
OK -10 -2 -7 => -276 []
OK -10 -2 -6 => -236 []
OK -10 -2 -5 => -196 []
OK -10 -2 -4 => -156 []
OK -10 -2 -3 => -116 []
OK -10 -2 -2 => -76 []
OK -10 -2 -1 => -36 []
OK -9 -2 -10 => -356 []
OK -9 -2 -9 => -320 []
OK -9 -2 -8 => -284 []
OK -9 -2 -7 => -248 []
OK -9 -2 -6 => -212 []
OK -9 -2 -5 => -176 []
OK -9 -2 -4 => -140 []
OK -9 -2 -3 => -104 []
OK -9 -2 -2 => -68 []
...
OK 10 -2 8 => -316 []
OK 10 -2 9 => -356 []
OK 10 -2 10 => -396 []
success: 2.1379980563654035 %
В правильном решении корни разбросаны на одинаковом расстоянии от -b, а в коде автора - от b. Совпасть оба сразу могут только в одном случае - b=0 и равны дискриминанты. Но при b=0 получаем вот такое уравнение: -(0 ^ 2 - 4*a*c) = 0*0 - 4*a*c
Отсюда: -2 + 4*a*c = -4*a*c, 8*a*c = 2, a*c = 1/4
Т.е. при b=0 или a и c должно быть дробным, что в коде автора недопустимо ;(
А задачи с одним корнем нет смысла подбирать из-за if (D=0), которое всегда false.
P.S. Если поменять int на float, то по идее прокатит что-нибудь типа a=1/8, b=0, c=2. Если поставить минусы перед b - дофига решений, например a=1, b=5, c=4.
Восхищаюсь способностью некоторых людей думать и анализировать.
Мне же хочется посмотреть, что получается и продолжать лениться.
В итоге думающие люди достигают просветления, а у меня лишь получается чуть упрощённый вариант, который по-прежнему делает полный перебор 🙁
var MIN = -10, MAX = 10;
var counter = 0;
for(var a = MIN; a <= MAX; ++a){
for(var b = MIN; b <= MAX; ++b){
for(var c = MIN; c <= MAX; ++c){
var D = b*b-4*a*c;
if(D < 0 && (b^2-4*a*c) + D === 0){
console.log('OK', a, b, c, '=>', D, '[]');
++counter;
}
}
}
}
console.log('success:', 100 * counter / Math.pow((MAX-MIN+1), 3), '%');
Перечитай тред внимательно. Я пару раз писал об этом. Первый раз просто написал эту строку и фейспалм. Второй раз сказал, что нет смысла тестить на уравнениях с одним корнем, т.к. в эту ветку не зайдет 😉
Так что писать -то? Это классический пример. Я бы даже сказал, что это романтика плюсов. Язык такой романтичный и загадочный, что может откомпилить почти все, но не так, как хочет молодой программист... Прям как женщина
В основном в момент инициализации. Если есть инициализатор - то по одной на строку, да. Если нет - то группирую по смыслу(!), не по типу. Примерно так:
int repetare = 0;
while (repetare < 100) {
float a, b, c;
// ... input ...
float d = b*b - 4*a*c;
if (d > 0) {
float x1 = (-b-sqrt(D)) / (2*a);
float x2 = (-b+sqrt(D)) / (2*a);
// ... output ...
} else if (d < 0) {
} else {
}
}
P.S. Я вообще больше одного оператора в строке стараюсь никогда не писать, даже если они очень короткие типа x += dx; y += dy;
> Вообще не люблю Дельфийское объявление переменных - в начале, да без инициализации...
Дельфины утверждают, что в нем переменные быстрее ищутся (конечно же если писать в блокноте, в нормальной IDE есть хоткеи для перехода на описание)...
если рукими искать... дай бог почти везде есть Go to declaration, go to implementation и find usages, а больше ничего не требуется.
В делфи(да и в паскале) это сделано для упрощение компиляции, как я понимаю(в смысле сам код не может содержать описания переменной, и когда просматривается код, все переменные уже известны)
"В паскале настолько сложно объявлять новые переменные, что программисты начинают думать, как использовать уже ненужные, оптимизируя тем самым использование памяти."
В каждой шутке есть доля шутки 😉 Используют же! Пару раз сам видел такую херню на делфи... Как минимум всякие i и j для циклов так абузят. То, что в нормальных компиляторах сишки (vc98 к ним не относится) видно только внутри цикла, тут торчит на всю функцию...
Но с нормальным оптимайзером вся эта рукотворная псевдооптимизация бесполезна. Он все равно знает, в какой момент переменная начинает работу, и до какого момента она нужна. И если у переменных области действия не пересекаются - сам положит их в один регистр\ячейку памяти.
> Используют же!
Вы так говорите, как будто это что-то плохое.
> с нормальным оптимайзером
Не подскажешь тонкости относительно паскалеоптимайзеров? Например FPC годен в том, про что ты говоришь? Или, может быть, GPC?
А то Тарас к бабке уехал, спросить не у кого.
> эта рукотворная псевдооптимизация бесполезна
Если при этом не создаются неудобства из за одинакового имени переменной для разных нужд, то почему бы и нет, ведь сущностей меньше, декларации короче.
Почему плохо реюзать переменную? А потому что потом сложно прослеживать глазами граф зависимостей. Хер поймешь, то ли в этом i могло остаться старое значение, то ли там уже новое. Особенно если переменная заполняется по условию. Лишние раздумия создает. А если функция и так маленькая - так инициализация совместно с описанием ее только читабельней и короче сделают.
Одноименные переменные мешают? Да не мешают они. В большинстве случаев, когда хочется запилить одинаковое имя переменной, оно будет внутри цикла или ифа. А там оно никому не мешает, и сразу понятно, что она нужна только внутри данного блока.
> FPC, GPC
gcc годен 🙂 А так - я думаю все паскалекомпиляторы уже давно умеют в нормальную оптимизацию. Даже делфи 7 должна уметь, поскольку при отладке оптимизнутой сборки пишет "variable optimized out" в точках, где переменная не юзается.
>Одноименные переменные мешают? Да не мешают они. В большинстве случаев, когда хочется запилить одинаковое имя переменной, оно будет внутри цикла или ифа. А там оно никому не мешает, и сразу понятно, что она нужна только внутри данного блока.
Поcему в кошерных языках есть перекрытие переменных и scope
>Даже делфи 7
На сколько я видел, паскалелюбы молятся на борланд. Может не туда смотрел)
Изначально в паскале при входе в функцию железобеттоно выделялась память под переменные, сейчас хз как там все.
Скорее всего так же, но с оптимизацией.
Кстати, нежелание обьявлять >9000 переменных ведет к тому, что создается много небольших функций вместо богофункций, что тоже неплохо
> при входе в функцию железобеттоно выделялась память под переменные
Железобетонно выделяется блок памяти != каждая переменная имеет свой слот в этом блоке. Если часть переменных окажутся в одном слоте (если они не юзаются одновременно), а часть вообще уйдут в регистры, то ничего в этой схеме не испортится 😉 Кроме дебаггера. Но дебаггер и оптимизация это отдельная история.
> Насколько я знаю, при D = 0 уравнение имеет два корня.
> Два одинаковых корня.
При a != 0 будет два корня, только не все к этому морально готовы.
Как и к некоторым другим случаям.
О мархуз, з лаби якого селюка ви це чудовисько витягнули...
> getche();
дай чо?
-1 потому что иначе ошибку выдавало?
Да ну? Где тут рашен?
> if(D=0)
facepalm.png
> D=(b^2-(4*a*c))*(-1);
> x1=(b-sqrt(D))/(2*a);
Сначала считаем корни, потом проверяем D>0, круто, че. Из-за этого походу и -1.
> считаем корни
Или это инты-не инты, или удачи считающим.
Попробовать подобрать такие значения, чтобы совпали иксы, насрав на некорректность дискриминанта? Но так не интересно ;(
Еще вариант приходит в голову - как-то сыграть на округлении к нулю, когда делят на 2*a.
1. Вероятность правильного решения с помощью этого кода падает с ростом (или ростом различия) a,b,c.
2. Вероятность получения правильного ответа для уравнения с 2 корнями крайне мала и скорее всего недостижима.
3. Для a,b,c из [-10; 10] решение работает правильно в 2% случаев.
Экспериментальная установка:
Некоторые результаты:
OK -10 -2 -10 => -396 []
OK -10 -2 -9 => -356 []
OK -10 -2 -8 => -316 []
OK -10 -2 -7 => -276 []
OK -10 -2 -6 => -236 []
OK -10 -2 -5 => -196 []
OK -10 -2 -4 => -156 []
OK -10 -2 -3 => -116 []
OK -10 -2 -2 => -76 []
OK -10 -2 -1 => -36 []
OK -9 -2 -10 => -356 []
OK -9 -2 -9 => -320 []
OK -9 -2 -8 => -284 []
OK -9 -2 -7 => -248 []
OK -9 -2 -6 => -212 []
OK -9 -2 -5 => -176 []
OK -9 -2 -4 => -140 []
OK -9 -2 -3 => -104 []
OK -9 -2 -2 => -68 []
...
OK 10 -2 8 => -316 []
OK 10 -2 9 => -356 []
OK 10 -2 10 => -396 []
success: 2.1379980563654035 %
Отсюда: -2 + 4*a*c = -4*a*c, 8*a*c = 2, a*c = 1/4
Т.е. при b=0 или a и c должно быть дробным, что в коде автора недопустимо ;(
А задачи с одним корнем нет смысла подбирать из-за if (D=0), которое всегда false.
P.S. Если поменять int на float, то по идее прокатит что-нибудь типа a=1/8, b=0, c=2. Если поставить минусы перед b - дофига решений, например a=1, b=5, c=4.
Мне же хочется посмотреть, что получается и продолжать лениться.
В итоге думающие люди достигают просветления, а у меня лишь получается чуть упрощённый вариант, который по-прежнему делает полный перебор 🙁
Бросить каку
Это крайняя степень извращения - тестировать черным ящиком, когда тест белым показал, что автору нужна эфтаназия
Написал.
int repetare=0;
int a;
int b;
int c;
int x1;
int x2;
Мне кажется, или это называется - извиняйте, парни, я на плюсах первый день, так то я всегда на делфи писал...
А вообще, если я описываю переменную с инициализацией - то я тоже посвящаю ей отдельную строку. Без инициализации да, сваливаю в кучу.
ну так и нужно. Это повышает читаемость кода.
> Если нет - то группирую по смыслу(!)
Еще один несомненный плюс
Между
float a, b, c;
и
float a;
float b;
float c;
есть разница - о ней я и говорил.
Вообще не люблю Дельфийское объявление переменных - в начале, да без инициализации...
Дельфины утверждают, что в нем переменные быстрее ищутся (конечно же если писать в блокноте, в нормальной IDE есть хоткеи для перехода на описание)...
В делфи(да и в паскале) это сделано для упрощение компиляции, как я понимаю(в смысле сам код не может содержать описания переменной, и когда просматривается код, все переменные уже известны)
Но с нормальным оптимайзером вся эта рукотворная псевдооптимизация бесполезна. Он все равно знает, в какой момент переменная начинает работу, и до какого момента она нужна. И если у переменных области действия не пересекаются - сам положит их в один регистр\ячейку памяти.
Вы так говорите, как будто это что-то плохое.
> с нормальным оптимайзером
Не подскажешь тонкости относительно паскалеоптимайзеров? Например FPC годен в том, про что ты говоришь? Или, может быть, GPC?
А то Тарас к бабке уехал, спросить не у кого.
> эта рукотворная псевдооптимизация бесполезна
Если при этом не создаются неудобства из за одинакового имени переменной для разных нужд, то почему бы и нет, ведь сущностей меньше, декларации короче.
Одноименные переменные мешают? Да не мешают они. В большинстве случаев, когда хочется запилить одинаковое имя переменной, оно будет внутри цикла или ифа. А там оно никому не мешает, и сразу понятно, что она нужна только внутри данного блока.
> FPC, GPC
gcc годен 🙂 А так - я думаю все паскалекомпиляторы уже давно умеют в нормальную оптимизацию. Даже делфи 7 должна уметь, поскольку при отладке оптимизнутой сборки пишет "variable optimized out" в точках, где переменная не юзается.
Поcему в кошерных языках есть перекрытие переменных и scope
>Даже делфи 7
На сколько я видел, паскалелюбы молятся на борланд. Может не туда смотрел)
Но делфи 7 это же и есть борланд 🙂 Или ты про досовский BP?
Не, я про то, что паскалелюбы сейчас только на делфи и пишут.
Это как пассивный курильщик? Сам не юзаю, но от соседей по ГК дым достается?
> Всегда читал ник пользователя bormand, как borland
Ну собственно так этот ник и был придуман. Переделал первое пришедшее на ум слово, когда регался.
P.S. Еще можно прочитать как borrnand, по аналогии с .pom файлами, которые многие читают как .porn.
Борман же Штирлицевский, просто конспирация.
Вы так говорите, как будто borland это что-то плохое.
bormand, Вы таки сделали дельфинопластику?
Скорее всего так же, но с оптимизацией.
Кстати, нежелание обьявлять >9000 переменных ведет к тому, что создается много небольших функций вместо богофункций, что тоже неплохо
Железобетонно выделяется блок памяти != каждая переменная имеет свой слот в этом блоке. Если часть переменных окажутся в одном слоте (если они не юзаются одновременно), а часть вообще уйдут в регистры, то ничего в этой схеме не испортится 😉 Кроме дебаггера. Но дебаггер и оптимизация это отдельная история.
Два одинаковых корня.
> Два одинаковых корня.
При a != 0 будет два корня, только не все к этому морально готовы.
Как и к некоторым другим случаям.