| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C++ Builder > Глюки на тригонометрии при углах в 90n градусов. |
| Автор: Mal Hack 5.1.2006, 15:51 | ||
Код:
При вводе имеем: 0: sin = 0, cos =1 90: sin = 1, cos = -2.7 180: sin = -5.4, cos = -1 К примеру на углах 45, 135, 405 все в норме. |
| Автор: BreakPointMAN 5.1.2006, 16:17 |
| Что-то я не помню таких функций, как Sin и Cos... хмм... А может, ошибка появляется при отображении? Ну, места там не хватает... или при преобразовании что-то случается... |
| Автор: _hunter 5.1.2006, 16:19 |
| насколько я помню они радианы принимают... + что за странное название ( с большой буквы )? в math.h с маленькой... |
| Автор: Illuminaty 5.1.2006, 16:29 | ||
а если напрямую написать?
|
| Автор: Mal Hack 5.1.2006, 16:40 |
| Не помогает. |
| Автор: Illuminaty 5.1.2006, 16:44 | ||
а что выводит при явном задании значения переменной angle ?
|
| Автор: _hunter 5.1.2006, 16:57 |
| стоп. все правтльно оно выдает. при 180 син не -5.4 а -5.4 * 10^(-20) ( т.е. 0 ) напиши что-то типа AngleGrid -> Cells[1][0] = AnsiString().sprintf("%.3f", Sin( angle ) ); |
| Автор: Partizan 5.1.2006, 17:14 | ||
У меня в BC++B6 результаты совершенно адекватные...
Выполнение этого кода даёт нам sin: 1,2246...........E-16 cos: 1 |
| Автор: Mal Hack 5.1.2006, 17:16 | ||||
"Что-то типа" не помогло. Помогло вот что:
Огромное тебе спасибо !!! Добавлено @ 17:16 Хотя каждый раз Round использовать не хочется |
| Автор: _hunter 5.1.2006, 17:22 |
| а что значит не помогло? минус мешает? так его убрать можно... или вообще так: if ( abs(sin) < 0.00000000001 ) sin = 0; написать а потом sprintf ему... |
| Автор: Mal Hack 5.1.2006, 17:34 |
| У косинуса при - был -0.000 Минус тут не при чем. Там 1 должна быть |
| Автор: _hunter 5.1.2006, 17:52 |
| похоже sprintf() с long double-ами не работает. приводи перед конвертацией к doublе -- всеравно все знаки пользователю вряд ли нужны... AnsiString().sprintf("%0.3f", (double)(Sin(DegToRad(angle)))); |
| Автор: Mal Hack 5.1.2006, 20:29 |
| _hunter сработало. Слу, а что лучше в плане быстродействия и грамотности кода? RoundTo или через sprintf? |
| Автор: _hunter 6.1.2006, 11:19 |
| интересный вопрос... sprintf точно не меделеннее ( потому как при RounTo/FormatFloat выполняются аналогичные операции ) а возможно и быстрее -- новое значение не создается ( RounTo ) в любом случае нужно эксперимент ставить а в полане грамотности ( а точнее красоты кода ) sprintf явно лучше |
| Автор: Mal Hack 6.1.2006, 15:04 |
| _hunter а с точки зрения грамотности будет выгоднее вынести это преобразование в отдельную функцию? При условии, что мне надо меня формат, т.е. кол-во отображаемых знаков после запятой? |
| Автор: _hunter 6.1.2006, 15:15 |
| в отдельную функцию смысла нет ( разве что читаемость немного повысить ) можно в том месте, где задается число знаков и формировать строку формата: formatStr = "%0." + IntToStr(precision) + "f"; AnsiString().sprintf(formatStr, (double)(Sin(DegToRad(angle)))); |
| Автор: Mal Hack 6.1.2006, 15:25 |
| Окей. Спасибо. Так и сделаю. |
| Автор: Mal Hack 6.1.2006, 18:20 | ||||||||||
Хм, пишу вот так:
Выдает:
или
Выдает:
Объявленно, как:
|
| Автор: Partizan 6.1.2006, 18:33 | ||||||
| Потому что слева у тебя char...а справа AnsiString... Писать нужно так:
или так...
Либо вообще так:
|
| Автор: Mal Hack 6.1.2006, 18:43 | ||||
Это в моем случае получается несколько не рационально. Воспользовался вариантом:
Эх, никак не могу привыкнуть, что AnsiString это не простая строка, а целый класс... Спасибо. Добавлено @ 18:43 Стоп. Выдает все равно [C++ Error] Unit2.cpp(39): E2277 Lvalue required |
| Автор: Partizan 6.1.2006, 18:49 | ||
| а...ну дык пральна... если уж ты остановился на том варианте переопредели Prec так
|
| Автор: _hunter 6.1.2006, 18:56 |
| + не понятно чем AnsiString не нравится. почему бы ее и не использовать? |
| Автор: Mal Hack 6.1.2006, 19:25 | ||||
Когда подставляю в формат, мне пишет несоответствие типов cont char * и AnsiString.
Пробовал. Ругается вот так: [C++ Error] Unit2.cpp(39): E2235 Member function must be called or its address taken Т.е. мы как-то не правильно в указатель пишем. |
| Автор: Partizan 6.1.2006, 19:58 | ||||||||||
когда подставляешь в формат не забывай вызывать !!!c_str()!!! Prec.c_str() - это у тебя должно быть в формате в случае AnsiString Prec;
гммм...щас посмотрим... E2235 Member function must be called or its address taken A reference to a member function must be called, or its address must be taken with & operator.... возможно ты опечатался... лично у меня следующий тест проходит на ура:
|
| Автор: Mal Hack 6.1.2006, 20:15 | ||
Вот тут выкидывает на таком же коде. |
| Автор: TIGERоX 6.1.2006, 22:12 | ||||
используя ансистринг
если не нравится замени на char
Все должно ботать |
| Автор: Mal Hack 6.1.2006, 22:51 | ||||||||
Не катит. Таже фигня. Может это уже особенности BDS, но факт остается фактом.
Такой вариант работает, но не хочу я каждый раз вызывать лишнюю функцию. В общем, сделал вот так:
Добавлено @ 22:39 Блин, а так AccessViolation выкидывает Добавлено @ 22:51
- Компилится, но когда подставляю формат, появляются какие-то квадраты |
| Автор: BreakPointMAN 6.1.2006, 23:14 | ||
НУ МАТЬ МОЯ ЖЕНЩИНА!..
Нельзя, блин, так, блин, делать... блин... ибо "("%." + IntToStr( PrecComboBox -> ItemIndex ) + "f")" это временный объект... Нельзя взять его char*-представление, и потом использовать этот адрес для инициализации указателя... Временный объект будет разрушен после выполнения этой строки, и по указателю фиг знает что будет лежать, блин. |
| Автор: Partizan 6.1.2006, 23:16 |
| А ты весь код приведи....вот и разберёмся... |
| Автор: Mal Hack 6.1.2006, 23:27 | ||||
Сразу надо было говорить Сделал так:
|
| Автор: Mal Hack 7.1.2006, 00:15 | ||||||
| Так, вроде бы со всем разобрался... Но есть такой глюк. Есть несколько вот таких функций, висящих на разных кнопках и изменяющих разные Edit'ы. (*)
Есть список, из 9 элементов, котоый дает уже знакомую точность. Вот у него идет обраюотка на OnChange. Вот функция
Как видно, она вызывает вот те самые функции (*) Так вот, когда я выбираю, все значения в этих функциях изменяют значения при выводе на новую точность. Все это работает. Но, вот если я выбрал точность, начиная с 4 ItemIndex или %0.3f, то если нажать на кнопку, все поля, которые должны пересчитаться - обнуляются. Why? Внутри функций Prec используется только как:
Т.е. Prec не ПЕРЕОПРЕДЕЛЯЕТСЯ в них. |
| Автор: _hunter 10.1.2006, 12:01 |
| странно. по коду граблей не видно... нужно отладчиком походить. а что будет если так: LogEdit10 -> Text = AnsiString().sprintf("%0.3f", (double) Log10( x ) ); написать? |
| Автор: Mal Hack 10.1.2006, 19:01 |
| Так все остается, как надо. Странно, но Prec изменяет свое значение при клике на кнопки. Почему? Фиг знает, ведь она там не изменяется. Я так чувствую, что где-то я очень глупо указатель использую. Вот прикладываю исходник. |
| Автор: teesync 27.7.2022, 05:10 |
Модератор: Сообщение скрыто. |