Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.64
G@leON
6 / 6 / 1
Регистрация: 02.06.2009
Сообщений: 99
#1

Ошибка преобразования типа - C++

10.05.2012, 01:35. Просмотров 1384. Ответов 32
Метки нет (Все метки)

Задача состояла в следующем: реализация алгоритма проверки n на простоту, используя малую теорему Ферма. В силу недостаточного опыта и позднего времени накумекал следующий код с пояснениями:

В качестве 1 из параметров, передаваемых функциям, выступает маркер простоты.
Это параметр-ссылка на переменную логического типа.
Значение маркера = true после выполнения подтверждает простоту проверяемого числа.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int gcd(int v_1, int v_2){
    while (v_2){
        int temp = v_2;
        v_2 = v_1 % v_2;
        v_1 = temp;
    }
    return v_1;
}
 
void ferma_lt_test(bool &prime_marker, int n){
    prime_marker = true;
    if (n<1){
        prime_marker = false;
        cout << "n is not natural" << endl;
    }
    if (n>2) {
        int v_1 = 2;
        while ((gcd(n,v_1)) != 1)
            v_1++;
        double deg_v = n, base_v = v_1;
        long l_v1 = exp(deg_v * log(base_v)), l_v2 = exp((deg_v - 1) * log(base_v));
        l_v1 %= n;
        l_v2 %= n;
        if ((l_v1 != v_1) || (l_v2 != 1))
            prime_marker = false;
    }
}
Здесь ф-ция gcd(v_1,v_2) - нахождение НОД. Вторая функция: Тест малой теоремой Ферма.

Ошибка заключается собственно в том, что при преобразовании double в long в строке:
C++ (Qt)
1
long l_v1 = exp(deg_v * log(base_v)), l_v2 = exp((deg_v - 1) * log(base_v));
Оба значение типа long на 1 меньше, чем возвращаемые функциями значения типа double. Притом, данная ошибка вылезает для чисел до 19 включительно. Число 23, как ни странно, проверяется. Помогите исправить.

Соответственно, число 31 уже выходит за границу допустимого диапазона. Было бы неплохо, так же, услышать подсказку по увеличению допустимого диапазона (например, имеется ли стандартный модуль(заголовок) длинной математики в C++, а если нет, то какой лучше и где найти...).

Добавлено через 52 минуты
После проверки на различные варианты преобразования выяснил, что они не помогают, ни преобразование в стиле C, не преобразование в стиле С++ (cast которые). Конечно, проблему можно разрешить проверкой на принадлежность к определенному числу (типа if n < 19 ... то прибавлять к функции +1), но это вообще не выход. Так что проблему надо решать альтернативным методом. Каким, не знаю.

Я так понимаю, задача вылазит несколько другим боком. Нужно как то умудрится возвести в степень n и n-1 число v_1, а результат потом делить на n с получением остатка от деления.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.05.2012, 01:35     Ошибка преобразования типа
Посмотрите здесь:

Ошибка преобразования типа в классе - C++
Дан класс, который реализует длинную арифметику с положительными\отрицательными целыми числами. Все числа одинаковой длины и их макс....

Преобразования массива с типа int к типу char - C++
Помогите решить задачу. Требуется создать шаблон класса для преобразования массива с типа int к типу char, помогите кто чем сможет буду...

Оператор преобразования типа и его эквивалентные замены, поиск строки в текстовом файле , содержащей заданный - C++
Господа, был бы очень признателен если бы кто то помог ответить на вапросы http://cs616225.vk.me/v616225102/122f8/5kAaFEGoDn0.jpg

Ошибка преобразования - C++
Вот мой код. В общем в конце выбивает &quot;error C2664: kasat: невозможно преобразовать параметр 5 из &quot;double (__cdecl *)(double,double)&quot;...

ошибка преобразования char - C++
помогите найти ошибку(или исправить): #include&lt;iostream&gt; #include&lt;string.h&gt; #include&lt;conio.h&gt; #include&lt;stdio.h&gt; ...

Ошибка преобразования класса - C++
Добрый день! Уважаемые, помогите пожалуйста найти ошибку. #include &lt;iostream&gt; #include &lt;stdio.h&gt; #include &lt;string.h&gt; #include...

Ошибка преобразования типов - C++
В чем именно я ошибся,если код ошибки #include &lt;iostream&gt; #include &lt;stdlib.h&gt; #include &lt;string&gt; #include &lt;ctype.h&gt; using...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Avazart
Эксперт С++
7115 / 5292 / 273
Регистрация: 10.12.2010
Сообщений: 23,381
Записей в блоге: 17
10.05.2012, 05:18     Ошибка преобразования типа #2
Что такое exp() и где оно живет?
G@leON
6 / 6 / 1
Регистрация: 02.06.2009
Сообщений: 99
10.05.2012, 05:32  [ТС]     Ошибка преобразования типа #3
Она из заголовка <math.h>
Давай так. Что бы проще было, вкладываю код юнита, заголовка и собственно main.
Вложения
Тип файла: rar Библиотеки проверки на простоту.rar (1.5 Кб, 5 просмотров)
Toshkarik
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
10.05.2012, 05:48     Ошибка преобразования типа #4
Avazart, exp()
Это вот эта теорема?
Avazart
Эксперт С++
7115 / 5292 / 273
Регистрация: 10.12.2010
Сообщений: 23,381
Записей в блоге: 17
10.05.2012, 06:02     Ошибка преобразования типа #5
У мня компилится без ошибок...

Добавлено через 7 минут
Toshkarik, Само выражение просто страшное, напомнило чем то шаблоны STL,подумал что exp() самописная а не экспонента (время позднее или точнее раннее)

Добавлено через 1 минуту
C++
1
2
long l_v1 = exp(deg_v * log(base_v));
long l_v2 = exp((deg_v - 1) * log(base_v));
G@leON
6 / 6 / 1
Регистрация: 02.06.2009
Сообщений: 99
10.05.2012, 06:07  [ТС]     Ошибка преобразования типа #6
Компилитс без ошибок, я вообщето писал что все ОК.
Ошибка в преобразовании. Преобразование он делает, но теряет 1.

Там где для компиляции я в выходной поток вставил результаты возведения:
void ferma_lt_test(bool &prime_marker, int n){
prime_marker = true;
if (n<1){
prime_marker = false;
cout << "n is not natural" << endl;
}
if (n>2) {
int v_1 = 2;
while ((gcd(n,v_1)) != 1)
v_1++;
double deg_v = n, base_v = v_1;
long l_v1 = exp(deg_v * log(base_v)), l_v2 = exp((deg_v - 1) * log(base_v));
cout << v_1 << " " << (l_v1) << " " << l_v2 << endl; //ЗДЕСЬ
l_v1 %= n;
l_v2 %= n;
if ((l_v1 != v_1) || (l_v2 != 1))
prime_marker = false;
}
}
Сделай вот так:
C++ (Qt)
1
cout << exp(deg_v * log(base_v)) << " " << (l_v1) << " " << l_v2 << endl;
И да, код в модуле уже модифицированный. Надо в модуль вставить код, который выше.
Avazart
Эксперт С++
7115 / 5292 / 273
Регистрация: 10.12.2010
Сообщений: 23,381
Записей в блоге: 17
10.05.2012, 06:14     Ошибка преобразования типа #7
Что значит "1"?

Добавлено через 5 минут
Поидее так должно быть
C++
1
2
long double l_v1 = (exp(deg_v * log(base_v)));
long double l_v2 = (exp((deg_v - 1) * log(base_v)));
если хочишь большую точность
Toshkarik
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
10.05.2012, 06:16     Ошибка преобразования типа #8
Так Вы уж определитесь, с какими типами работаете, не удивительно, что есть погрешность при преобразовании вещественного типа в целочисленный.
G@leON
6 / 6 / 1
Регистрация: 02.06.2009
Сообщений: 99
10.05.2012, 06:19  [ТС]     Ошибка преобразования типа #9
Мне дальше надо делить с получением остатка. Поэтому мне надо получить целочисленное.
Ни 1 из вещественных типов не обрабатывается оператором %.

Единица в смысле в значении. Например 13.
2^13 это 8192, а результат после long l_v1 = exp(deg_v * log(base_v)) равен 8191.

И я понимаю, что это некрасиво. С точки зрения машины все правильно, но я то понимаю, что есть погрешность при преобразовании вещественного типа в целочисленный. Просто тип double не делится с остатком))
Toshkarik
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
10.05.2012, 06:21     Ошибка преобразования типа #10
Для этого есть функция fmod().
Avazart
Эксперт С++
7115 / 5292 / 273
Регистрация: 10.12.2010
Сообщений: 23,381
Записей в блоге: 17
10.05.2012, 06:21     Ошибка преобразования типа #11
Может человек имеет ввиду округление, а не приведение типов?
Toshkarik
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
10.05.2012, 06:22     Ошибка преобразования типа #12
А чем при возведении в степень не устроила функция pow()?
Avazart
Эксперт С++
7115 / 5292 / 273
Регистрация: 10.12.2010
Сообщений: 23,381
Записей в блоге: 17
10.05.2012, 06:24     Ошибка преобразования типа #13
Выглядит не так страшно
Toshkarik
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
10.05.2012, 06:27     Ошибка преобразования типа #14

Не по теме:

Avazart,


G@leON, если хотите сохранить свой код, то попробуйте сделать вот так
C++
1
2
long l_v1 = floor( exp(deg_v * log(base_v)) + .5 ),
     l_v2 = floor( exp((deg_v - 1) * log(base_v)) + .5 );
G@leON
6 / 6 / 1
Регистрация: 02.06.2009
Сообщений: 99
10.05.2012, 06:36  [ТС]     Ошибка преобразования типа #15
Во, fmod - то, что нужно.
floor - это тоже хорошо.
А функция pow(), она конечно хороша, просто такая форма возведения мне понятна. А код pow() мне смотреть лень. Хотя разницы нет (наверное))).
Всем СПАСИБО
Toshkarik
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
10.05.2012, 06:39     Ошибка преобразования типа #16
Цитата Сообщение от G@leON Посмотреть сообщение
Хотя разницы нет (наверное)
Скорей всего есть. Использование pow() имеет вид:
double pow( base, exponent );
То-есть в Вашем случае просто нужно было написать
C++
1
long l_v1 = pow( v_1, n );
G@leON
6 / 6 / 1
Регистрация: 02.06.2009
Сообщений: 99
10.05.2012, 06:52  [ТС]     Ошибка преобразования типа #17
Цитата Сообщение от Toshkarik Посмотреть сообщение
Скорей всего есть. Использование pow() имеет вид:
double pow( base, exponent );
То-есть в Вашем случае просто нужно было написать
C++
1
long l_v1 = pow( v_1, n );
Кстати да, попробовал предсавленный код, он тоже верный. Но......
И использовать его проще, что б нафиг на парится)) Оставлю с pow(). Все таки странно. exp() преобразуется с потерей 1 в значении. А после pow() все замечательно. Как так?
Toshkarik
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
10.05.2012, 07:03     Ошибка преобразования типа #18
Вещественные числа в компьютерных системах представляются приблизительно. Они не могут быть точными в отличии от целых чисел. Вы вызываете функцию log внутри exp, что только усугубляет положение. При присваивании вещественного типа целочисленному отбрасывается дробная часть. Могу предположить, что в данном случае получалось, например, число вроде 18.9234... и так далее, что при приведении давало целое 18 вместо 19. Поэтому Вам подкинул идею с функцией floor, которая округляет вещественное число до наибольшего целого не превосходящее само число. Ее часто используют для округления вещественного числа до ближайшего целого в виде
floor( val + .5 );
G@leON
6 / 6 / 1
Регистрация: 02.06.2009
Сообщений: 99
10.05.2012, 07:14  [ТС]     Ошибка преобразования типа #19
Цитата Сообщение от Toshkarik Посмотреть сообщение
Вещественные числа в компьютерных системах представляются приблизительно. Они не могут быть точными в отличии от целых чисел. Вы вызываете функцию log внутри exp, что только усугубляет положение. При присваивании вещественного типа целочисленному отбрасывается дробная часть. Могу предположить, что в данном случае получалось, например, число вроде 18.9234... и так далее, что при приведении давало целое 18 вместо 19. Поэтому Вам подкинул идею с функцией floor, которая округляет вещественное число до наибольшего целого не превосходящее само число. Ее часто используют для округления вещественного числа до ближайшего целого в виде
floor( val + .5 );
Ага, понятно, по крайне мере удалось выяснить методом научного втыка, что применение ф-ции fmod() иже с ней требует ф-ции floor(), без нее сравнения не получается.

Не по теме:

А ставить несколько спасибо можно? А то меня порадовало конечно .

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.05.2012, 07:23     Ошибка преобразования типа
Еще ссылки по теме:

Ошибка в функции преобразования Фурье - C++
Здравствуйте! Делаю гитарный тюнер, и застряла на моменте определения частоты уже снятого с микрофона звука. Звук с микрофона снимается в...

Ошибка в функции преобразования времени - C++
Как можно или нужно написать программу, которая, при вводе с клавиатуры, делает преобразования времени при помощи двух функций. Одна...

Динамический массив структур. Ошибка преобразования типов - C++
Всем привет есть задачка на структуры. Нужно через структуру В сделать динамический массив структуры А. Написал функцию, но компилятор...

Ошибка: "Значение типа float нельзя присвоить сущности типа int" - C++
При компиляции в Visual C++ получается такая ошибка: &quot;Значение типа float нельзя присвоить сущности типа int&quot;. Восьмая строка #include...

Ошибка "преобразования" параметра - C++
Доброго времени суток! Вылетает ошибка: error C2664: Dictionary::deleteNode: невозможно преобразовать параметр 1 из 'char ' в 'char' ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
10.05.2012, 07:23     Ошибка преобразования типа #20
Цитата Сообщение от G@leON Посмотреть сообщение
адача состояла в следующем: реализация алгоритма проверки n на простоту, используя малую теорему Ферма. В силу недостаточного опыта и позднего времени накумекал следующий код с пояснениями:
В качестве 1 из параметров, передаваемых функциям, выступает маркер простоты.
Это параметр-ссылка на переменную логического типа.
Значение маркера = true после выполнения подтверждает простоту проверяемого числа.
Зачем здесь лишний параметр? Проще возвращать по имени самой функции ретоном и не мучаться.
Yandex
Объявления
10.05.2012, 07:23     Ошибка преобразования типа
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru