6 / 6 / 2
Регистрация: 02.06.2009
Сообщений: 99
|
|||||||||||
1 | |||||||||||
Ошибка преобразования типа10.05.2012, 01:35. Показов 2417. Ответов 32
Метки нет (Все метки)
Задача состояла в следующем: реализация алгоритма проверки n на простоту, используя малую теорему Ферма. В силу недостаточного опыта и позднего времени накумекал следующий код с пояснениями:
В качестве 1 из параметров, передаваемых функциям, выступает маркер простоты. Это параметр-ссылка на переменную логического типа. Значение маркера = true после выполнения подтверждает простоту проверяемого числа.
Ошибка заключается собственно в том, что при преобразовании double в long в строке:
Соответственно, число 31 уже выходит за границу допустимого диапазона. Было бы неплохо, так же, услышать подсказку по увеличению допустимого диапазона (например, имеется ли стандартный модуль(заголовок) длинной математики в C++, а если нет, то какой лучше и где найти...). Добавлено через 52 минуты После проверки на различные варианты преобразования выяснил, что они не помогают, ни преобразование в стиле C, не преобразование в стиле С++ (cast которые). Конечно, проблему можно разрешить проверкой на принадлежность к определенному числу (типа if n < 19 ... то прибавлять к функции +1), но это вообще не выход. Так что проблему надо решать альтернативным методом. Каким, не знаю. Я так понимаю, задача вылазит несколько другим боком. Нужно как то умудрится возвести в степень n и n-1 число v_1, а результат потом делить на n с получением остатка от деления.
0
|
10.05.2012, 01:35 | |
Ответы с готовыми решениями:
32
Ошибка преобразования типа в классе Ошибка преобразования: значение типа "float *" нельзя присвоить сущности типа "float" Оператор преобразования типа в классах Оператор преобразования типа в char* |
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
|
||||||
10.05.2012, 07:23 | 21 | |||||
Посмотрел функцию решета Эратосфена - можно свести к более простому варианту:
1
|
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
|
|
10.05.2012, 07:25 | 22 |
0
|
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
|
|
10.05.2012, 07:28 | 23 |
Тем, что при округлении берется ближайшее целое, при приведении же просто отбрасывается дробная часть.
0
|
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
|
||||||
10.05.2012, 07:44 | 24 | |||||
А при чём здесь ошибка приведения? Ошибка приведения, это когда вообще нельзя привести. А здесь погрешность округления. Твой double чуть меньше ожидаемого целого.
Существует как минимум 4 способа округления: вниз, вверх, по математическим правилам и так называемое банкирское, по правилам которого если дробная часть точно равна 0.5, то округляют к ближайшему чётному, а в остальных случаях к ближайшему целому, при округлении вниз дробная часть отбрасывается, при округлении вверх при ненулевой дробной части инкремируется целая, а при нулевой сохраняется и после этого отбрасывается дробная часть, а оператор приведения типа может быть написан как угодно и предусматривать какое нибудь вообще пятое округление. В любом случае обнуление младших разрядов в какой либо системе счисления есть округление (округлять можно и до сотен, и до сотых), а приведение к целому всегда обнуляет все разряды с весами меньше единицы, что есть округление до целого. То, что встроенные типы принято приводить именно округлением вниз, сути не меняет. Добавлено через 6 минут Если и основание, и показатель целые, то зачем возводить в степень через экспоненту? Для данного случая степень определена, как произведение одинаковых множителей, так и делай.
1
|
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
|
|
10.05.2012, 07:46 | 25 |
Думаю, тут уместно обсуждение математического округления а не каких то там "банкирских" и тд.
Приведение типа, как я считаю, никак не связанно с округлением. Не как угодно, отбрасывается именно дробная часть.
0
|
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
|
|||||||||||
10.05.2012, 07:51 | 26 | ||||||||||
Как угодно. Конкретный способ принят только для стандартных типов и является всего лишь вопросом выбора авторов стандарта. Для своих типов ты можешь сделать даже так: если дробная часть строго меньше 0.5, то вверх, иначе вниз. И это тоже будет округление. Или можешь сделать математическое округление до кратного трём.
0
|
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
|
|
10.05.2012, 07:54 | 27 |
При чем тут не стандартные типы? Вы тут видите приведение не стандартных типов? Для стандартных типов точно указано, что получится в итоге, и это никак не связанно с округлением. Это форум С++, если Вы вдруг упустили это из виду.
0
|
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
|
|
10.05.2012, 08:03 | 28 |
Для стандартных был выбран один из способов округления, выбор закрепили. И всего делов. Приведение стандартного вещественного к целому, это округление вниз до целого, а не что то абсолютно новое.
0
|
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
|
|
10.05.2012, 08:07 | 29 |
Я же считаю, что данный способ был выбран исходя из природы чисел. Целое на то и целое, что в нем нет дробной части, поэтому она отбрасывается, и это не округление.
0
|
6 / 6 / 2
Регистрация: 02.06.2009
Сообщений: 99
|
|
10.05.2012, 08:18 [ТС] | 30 |
За решето спасибо, удобный способ, по поводу приведения типов, это именно ошибка приведения, просто это не ошибка синтаксиса, а ошибка компиляции некрасивой логики. И да, именно с округлением она и связана, так что в формулировке не вижу повода сомневаться.
По поводу параметра ссылки, а какая разница, передаете вы через параметр-ссылку, или просто возвращаете значение? Если вопрос удобства, то мне удобней через параметр-ссылку (либо параметр-указатель). Мне так логика понятней кажется.
0
|
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
|
|
10.05.2012, 08:20 | 31 |
Это именно округление. Отбрасывание дробной части есть округление вниз. А по какому принципу выбирали - вторично. Мне кажется, что выбрали вниз потому, что так проще. Но мотив выбора реализации не имеет ни какого отношения к наименованию операции.
0
|
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
|
|
10.05.2012, 08:23 | 32 |
taras atavin, пусть каждый останется при своем мнении. Я по другому смотрю на приведение типа в данном случае, и оно никак не вяжется с округлением.
0
|
10.05.2012, 17:41 | 33 |
Не путайте округление к ближайшему целому (то к которому нас в школе учили) и округление к меньшему(то которое предусмотрено ф-цией floor(), и впринципе происходит при в данном случаее при приведении).
И дело не в не правильном приведении типов, а в незнании того к чему оно приводит.... http://ru.wikipedia.org/wiki/Округление
0
|
10.05.2012, 17:41 | |
10.05.2012, 17:41 | |
Помогаю со студенческими работами здесь
33
Преобразования массива с типа int к типу char Оператор преобразования типа и его эквивалентные замены, поиск строки в текстовом файле , содержащей заданный Массивы и строки: реализовать метод ldtoms() для преобразования числа типа long double в денежную строку В массив типа double записываю целые числа (типа int), но ошибка не вылазиет! Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |