Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Математические пакеты > Помогите с Matlab |
Автор: stinker 1.7.2013, 08:03 |
По заданию нужно составить код по нахождению быстрого обратного квадратного корня. Код не ахти как сделал, но результат выходит подозрительно не тот(отрицательное число). Помогите пожалуйста доработать, чтобы работала правильно x = 29; half = 0.5*x; i = uint32(x); i = hex2dec('5f3759df') - bitshift(i,-1); x = double(i); x = x*(1.5 - half*x*x); |
Автор: Guinness 1.7.2013, 11:57 |
Как Вы думаете, что делают операторы uint32 и double? Если знаете, то именно это Вы хотели получить? |
Автор: Guinness 1.7.2013, 14:31 | ||||
В общем-то, в гугле вторая ссылка(пример на яве) все бы Вам разъяснила. На самом деле Вам нужно представление числа double как 32-битное целое. А этими операциями Вы преобразуете число double к uint32 и соответственно обратно.
|
Автор: stinker 1.7.2013, 14:50 | ||||||||
Эти ссылки я смотрел, и ещё пару десятков. Не очень силён в языках поэтому и обращаюсь за помощью. Тоесть Вы хотите сказать что double в конце не нужен? Добавлено через 1 минуту и 38 секунд сейчас код выглядит вот так
Добавлено через 3 минуты и 58 секунд Следуя алгоритму представление числа как 32-битное целое нужно на этапе вычитания из магического числа, при вычислении метода Ньютона нужно снова число с плавающей запятой. Если не прав поправте пожалуйста. |
Автор: Guinness 1.7.2013, 14:59 | ||
Все так. Просто число http://ru.wikipedia.org/wiki/Число_двойной_точности - это знаковый бит + эскспонента + мантисса. И Вам нужно именно это представление, а не перевод из double в uint как я показывал постом выше. Понятно? |
Автор: stinker 1.7.2013, 15:03 | ||||
Тоесть если я Вас правильно понял из double в unit перевод не нужен? тогда каким же образом можно представить число как целое? просто убрав unit изменений в конечном результате нет. Большое спасибо, что помогаете. |
Автор: Guinness 1.7.2013, 15:04 |
В общем, не буду Вас мучить. Вот ссылки на две функции, которые Вам нужны: http://www.mathworks.com/help/matlab/ref/num2hex.html http://www.mathworks.com/help/matlab/ref/hex2num.html Если не ошибаюсь, они Вам помогут. Проверьте на каких либо простых значениях, типа 25, 36 и т.п. Матлаба под рукой нет, так что у себя проверить не могу. Если нужно могу на C++ выложить. |
Автор: stinker 1.7.2013, 15:05 |
Как я понимаю мне нужно согласно алгоритму предствавить не в double(двойной точности), а в одинарной точности. Не могли бы Вы подсказать каким образом? |
Автор: Guinness 1.7.2013, 15:09 |
http://www.mathworks.com/help/symbolic/mupad_ref/float.html, это не работает? |
Автор: stinker 1.7.2013, 15:09 | ||
Большое спасибо! Но при замене, теперь выходит ошибка логического сдвига "Undefined function or method 'bitshift' for input arguments of type 'char'." |
Автор: Guinness 1.7.2013, 15:12 | ||
Интерпритатор говорит Вам, что не может применить данную операцию к строке. Соответственно, перевидете строку в целое число как Вы делали выше с помощью hex2dec. |
Автор: stinker 1.7.2013, 15:14 | ||
также выдаёт ошибку |
Автор: Guinness 1.7.2013, 15:19 |
=) можно код посмотреть? ![]() |
Автор: stinker 1.7.2013, 15:20 | ||||||
большое спасибо за обьяснение, это сработало. Но теперь у меня возник вопрос- уместен ли hex2num вместо double, если мы уже провели hex2dec? нужно ли в промежутке сделать hex2dec, а после провести hex2num? Добавлено через 2 минуты и 57 секунд
вот собсно код
Добавлено через 7 минут и 3 секунды Если Вам это поможет, то вот код из С++, на который я опирался
|
Автор: Guinness 1.7.2013, 15:28 | ||
Вы прочитали ссылку на вики про double? Давайте так, как будет выглядить: num2hex( double( 45 ) ) = ? num2hex( uint32( 45 ) ) = ? Не очень понял, где Вы это хотите делать? |
Автор: stinker 1.7.2013, 15:36 | ||||
Да, я прочёл её уже не первый раз, уже доходил до этой ссылки, в случае с unit выдаёт ошибку, в случае с double '4046800000000000' хотел это сделать перед итерацией, но увы, также выдёт ошибку. Добавлено через 6 минут и 14 секунд Вы указали, что double нужно заменить на hex2num, но поясните пожалуйста, зачем? ведь вычисление до double уже было в hex2dec? |
Автор: stinker 1.7.2013, 16:04 |
num2hex должен просто перевести число в шестнадцатеричное, т.е например 29 это 1D. матлаб же показывает что 29 это 4a191c2b54d4c50a. я просто неправ или оно так и должно ![]() Добавлено @ 16:07 Огроное спасибо за помощь, но теперь я вообще запутался чего матлаб от меня хочет ![]() даже переводя числа, они всеравно в результате остаются с большими степенями изза магического числа. ![]() помогите пожалуйста с этим безумным кодом |
Автор: Guinness 1.7.2013, 16:13 | ||||
Вы немного не так прочитали описание данной функции + пока не понимаете, что такое double. 1D - это представление 29 как целого числа. Добавлено @ 16:14
Ибо double большеват для этого преобразования. |
Автор: stinker 1.7.2013, 16:16 | ||||||
Но ведь в данном случае мне и нужно сделать его представлением целого, так ведь? Добавлено через 2 минуты и 19 секунд
тогда при выполнении этого выдаёт ??? Input argument "ExpBits" is undefined. Error in ==> float at 54 DAStudio.error('Shared:numericType:customFloatSupportRemove', TotalBits, ExpBits ); Добавлено через 5 минут и 27 секунд может быть это изза старого матлаба? |
Автор: Guinness 1.7.2013, 16:23 | ||
Да, но double в памяти хранится как число, которое делится на 3 части: знак + экспонента + мантисса. Тип int хранится как обычное число в двоичном виде: знак + значение. И Вам в алгоритме от double нужно представление как он хранится в памяти. В алгоритме на c++ происходят следующие вещи: 1) &x - мы передаем адрес на ячейку памяти, в которой хранится число double(знак + экспонента + мантисса) 2) (uint32 *)&x - говорим, что указатель указывает на ячейку памяти простое целое беззнаковое число(знак + значение) 3) *( (uint32 *)&x ) - значение находящееся по данному адресу как число uint32. Т.е. мы берем представление числа double как оно хранится в памяти компьютера. |
Автор: stinker 1.7.2013, 16:24 | ||
судя по хелперу float может задавать только структуру значения, при этом конкретное значение не присвоить. пример из тогоже хелпера
|
Автор: Guinness 1.7.2013, 16:29 | ||
Странно, сейчас до дома доеду посмотрю. |
Автор: stinker 1.7.2013, 16:41 |
вместо double по идее нужен single, т.к по алгоритму идут числа с одинарной точностью? |
Автор: stinker 1.7.2013, 16:59 |
по идее ведь float в маткаде это и есть double? Добавлено через 12 минут и 39 секунд хотя нет, при single получается отрицательное число.. |
Автор: stinker 1.7.2013, 18:11 |
Помогите пожалуйста доделать программу, очень прошу) пользовался вот этой литературой, но далеко не продвинулся. помогите пожалуйста) А то уже за вторую неделю мозг в кашу ![]() |
Автор: Guinness 1.7.2013, 19:09 |
Да, похоже нужно single использовать. С чем у Вас ещё проблемы остались? |
Автор: stinker 1.7.2013, 19:15 | ||
на данный момент код выглядит так:
какие в коде сейчас ошибки и обьясните пожалуйста как их можно исправить очень прошу, просто давно с этим кодом бьюсь, вроде и исправляю а результат тотже. ![]() в ответе явно не обратный корень, отрицательное число в безумной степени явно не то( Добавлено через 1 минуту и 47 секунд а по сути от сингла мало что изменилось, результат даже значения не сменил |
Автор: Guinness 1.7.2013, 19:22 |
x = single(i); меняем на x = single( hex2num( dec2hex( i ) ) ); |
Автор: stinker 1.7.2013, 19:26 | ||
в результате выходит значение "-Inf", минус бесконечность собсна Добавлено @ 19:33 ой, извините, не в ту программу код поставил) теперь понял что нужно было обращать i обратно в hex, потом в num, прям прояснило) Добавлено @ 19:34 огромное спасибо что помогли! так, если в результате у нас должен быть обратный квадратный корень, к примеру 29, то 1/sqrt(29)=0.185695338177052 а у нас по результатам кода выходит 1.3516559e-08 это нормально? или расчёты ошибочны? |
Автор: Guinness 1.7.2013, 19:38 |
Да я вот что-то тоже не понимаю, почему не получается, сейчас прогоняю. На крестах работало все) |
Автор: stinker 1.7.2013, 19:38 | ||
ого, всё разобрался! прям огромнющее спасибо вам! последний вопрос- как задать повторение итеранции, т.е последней строки? Добавлено через 1 минуту и 34 секунды
просто итерация метода ньютона даёт приближенное число, при большем повторении число уточняется! я повторил его n-число раз, т.е жал F9 около20 раз и число стало точным ответом! |
Автор: Guinness 1.7.2013, 19:40 | ||
я может что не понимаю, но bitshift что-то не то делает Добавлено через 49 секунд
у меня на первом шаге на плюсах было отличие в 6 знаке |
Автор: stinker 1.7.2013, 19:43 |
изначально разбирался на двоичных кодах, логическое смещение вправо вроде работает исправно |
Автор: Guinness 1.7.2013, 19:47 | ||
Да, это меня переклинило. |
Автор: stinker 1.7.2013, 19:53 |
может стоит задать цикл? |
Автор: Guinness 1.7.2013, 19:53 |
В общем все понятно, мы hex2num переводим в double, а нам нужно в single. http://stackoverflow.com/questions/7207413/convert-hex-to-single-precision |
Автор: stinker 1.7.2013, 19:59 | ||
Тоесть нужно добавить single в hex2num? |
Автор: Guinness 1.7.2013, 20:02 | ||
В общем, вот что получилось. |
Автор: stinker 1.7.2013, 20:12 | ||||
значит вся проблема была в double приближенное значение с разницей в 0,0002 ![]() Большое спасибо Вам за помощь и обьяснение! |