1 / 1 / 0
Регистрация: 29.09.2011
Сообщений: 17
1

Fast Inverse Square Root: перевод с C++ на Matlab

30.06.2013, 12:25. Показов 4402. Ответов 30
Метки нет (Все метки)

C++
1
2
3
4
5
6
7
8
9
float InvSqrt(float x)
{
float xhalf = 0.5f*x;
int i = *(int*)&x; 
i = 0x5f3759df - (i>>1);
x = *(float*)&i;
x = x*(1.5f-xhalf*x*x); 
return x;
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.06.2013, 12:25
Ответы с готовыми решениями:

ошибка square root
Вообщем переделал программу, которая считает методом Гаусса-Зейделя #include "stdafx.h" #include...

Floating Point:Square Root of Negative Number
После запуска программы в Borland C++ вылезает следующая ошибка Floating Point:Square Root of...

Перевод из С++ в Matlab
Помогите перевести #include <iostream> using namespace std; int main() { int n=3,i,j; ...

Перевод с MatLab
Нужна помощь - перевести функцию с MatLab на C++ или просто описать алгоритм. Эта функция...

30
5203 / 3536 / 368
Регистрация: 02.04.2012
Сообщений: 6,447
Записей в блоге: 17
30.06.2013, 15:37 2
Ох! Сишные руны! Тут без псилоцибе не постичь
Слух, а может зная само задание, будет проще его повторить в матлабе? или ты сам не знаешь, что делает эта функция?
1
23 / 20 / 0
Регистрация: 18.06.2013
Сообщений: 83
30.06.2013, 17:17 3
Похоже, что это вычисление быстрого обратного квадратного корня http://ru.wikipedia.org/wiki/%... 0%BD%D1%8C
А нельзя просто этим заменить?
Matlab M
1
uint32(1/sqrt(x))
1
5203 / 3536 / 368
Регистрация: 02.04.2012
Сообщений: 6,447
Записей в блоге: 17
30.06.2013, 17:35 4
@Pigmalion, если х - целое, то 1/sqrt(х) будет дробным, причем меньше 1, а если эту дробь перевести в uint32 (т.е. целое беззнаковое) то получим 0! Вот гляди:
Matlab M
1
2
3
4
5
6
7
>> uint32(1/sqrt(36))
ans =
           0
 
>> 1/sqrt(36)
ans =
    0.1667
1
23 / 20 / 0
Регистрация: 18.06.2013
Сообщений: 83
30.06.2013, 17:44 5
Да,действительно. Я то думал это "x" в 32-битное число переведёт)
0
5203 / 3536 / 368
Регистрация: 02.04.2012
Сообщений: 6,447
Записей в блоге: 17
30.06.2013, 17:53 6
*кстать 1/sqrt(uint32(36)) дает ошибку.
0
1 / 1 / 0
Регистрация: 29.09.2011
Сообщений: 17
30.06.2013, 19:22  [ТС] 7
Извините что сразу не указал, потом редактирование не работало.
Да, нужно найти быстрый обратный квадратный корень.
Следуя алгоритму вот вроде как-то так вышло, но застрял на итерации метода ньютона, т.е последней строке(врядтли верна, т.к выдаёт отрицательное число).
Если есть ещё ошибки помогите пожалуйста разобратся)
Matlab M
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
clc;
clear all;
close all;
x=29;
del=x/2;
xb=de2bi(x);
aa(1)=xb(4);
aa(2)=xb(3);
aa(3)=xb(2);
aa(4)=xb(1);
%hex=5f3759df;
hexdec=hex2dec('5f3759df');
aad=bi2de(aa);
i=hexdec-aad;
f=i*(1.5-del*i*i);
0
5203 / 3536 / 368
Регистрация: 02.04.2012
Сообщений: 6,447
Записей в блоге: 17
30.06.2013, 19:26 8
Цитата Сообщение от stinkerkiller Посмотреть сообщение
aa(1)=xb(4);
aa(2)=xb(3);
aa(3)=xb(2);
aa(4)=xb(1);
жееесть я набросал так:
Matlab M
1
2
3
4
5
6
7
8
clear, clc
 
x = 36;
half = 0.5*x;
i = uint32(x); 
i = hex2dec('5f3759df') - bitshift(i,-1);
x = double(i);
x = x*(1.5 - half*x*x)
Но результат мне совсем не нравится :/

*метод Ньютона правильный, вот кстать функция рассчета корня:
Matlab M
1
2
3
4
5
6
7
8
9
10
R = 16;
e = 0.001;
 
xs = R; % начальное приближение
xn = 0.5*( xs + R/xs );
while abs(xn-xs)>e
    xs = xn; % предыдущее значение
    xn = 0.5*( xs + R/xs ); % новое значение
end
xn
1
1 / 1 / 0
Регистрация: 29.09.2011
Сообщений: 17
30.06.2013, 19:46  [ТС] 9
Спасибо большое за помощь
Оба кода выдают одинаковые результаты, но число бесноватое какое-то. разве отрицательное здесь уместно?
Matlab M
1
x = x*(1.5 - half*x*x)
если в скобках поставить плюс то будет выглядеть получше, но тогда несоответствие формуле, наверное

Добавлено через 12 минут
Может ошибка в самом коде, а не в методе ньютона?помогите пожалуйста,я просто трамвай в матлабе
0
5203 / 3536 / 368
Регистрация: 02.04.2012
Сообщений: 6,447
Записей в блоге: 17
30.06.2013, 19:49 10
я видел несколько таких программ на С но везде стоит минус
если честно, ума не приложу в чем проблема
1
1 / 1 / 0
Регистрация: 29.09.2011
Сообщений: 17
01.07.2013, 09:55  [ТС] 11
если за х брать отрицательное число то вроде как тоже избавляемся от минуса, но взяв на калькуляторе теже числа там даже приблизительно не то

Добавлено через 13 часов 46 минут
ап ап ап
0
5203 / 3536 / 368
Регистрация: 02.04.2012
Сообщений: 6,447
Записей в блоге: 17
01.07.2013, 10:09 12
stinkerkiller, слух а есть ли вообще смысл в этих извращениях? Одно дело, если б мы работали с С без математической библиотечки, а тут его величество MATLAB гораздо быстрее и точнее посчитает 1/sqrt(x)
0
1 / 1 / 0
Регистрация: 29.09.2011
Сообщений: 17
01.07.2013, 10:17  [ТС] 13
Так задание звучит, бессмысленно и беспощадно уже дня 3 ломаю мозг чёго не так(
Маткад даёт теже результаты, наверное где-то в самом алгоритме накосячил, иль число такое и должно быть
0
5203 / 3536 / 368
Регистрация: 02.04.2012
Сообщений: 6,447
Записей в блоге: 17
01.07.2013, 10:18 14
Хорошо, а что должно быть на входе и что должно получить?
0
1 / 1 / 0
Регистрация: 29.09.2011
Сообщений: 17
01.07.2013, 13:29  [ТС] 15
На исходные данные идёт 32 битное число с плавающей запятой одинарной точности,судя по алгоритму.
и в результате получается приблизительное значение обратного квадратного корня
Соотнёс с алгоритмом
Добавлено через 11 минут
Matlab M
1
2
3
4
5
6
7
8
9
10
clear, clc
 
x = 29; %Алгоритм принимает 32-битное число с плавающей запятой 
        %(одинарной точности) в качестве исходных данных
half = 0.5*x; %вычисляет половину значения числа и сохраняет для дальнейшего использования
i = uint32(x); %трактуя 32-битное с плавающей запятой как 32-битное целое
i = hex2dec('5f3759df') - bitshift(i,-1);%производит логический сдвиг вправо на один бит 
                                          %и вычитает число из «магической» константы 5f3759df16
x = double(i); %Переводим результат в 32-битное число с плавающей запятой, получается первое приближение обратного квадратного корня исходного числа
x = x*(1.5 - half*x*x); %вычисляет одну итерацию метода Ньютона для получения более точного приближения
Добавлено через 3 минуты
строка
Matlab M
1
i = uint32(x)
давала в результате 0.
подставил в строку х
Matlab M
1
i = hex2dec('5f3759df') - bitshift(x,-1)
не делая это изменение, получалось что в результате мы просто отнимали ноль.
ответ в корне изменился. но не намного лучше. в этом случае он теперь 2.994672008689611e+87. избавился от отрицательного числа, но степеень

Добавлено через 12 минут
причём i = uint32(x) обращает в ноль всё подряд

Добавлено через 7 минут
Всеравно всякий бред выдает спаситепомогите

Добавлено через 1 час 43 минуты
возможна ли проблема в магическом числе? в расчётах "в лоб" такие безумные числа выходят конкрентно из-за него.

Добавлено через 45 минут
Ни у кого никаких идей нет?
0
5203 / 3536 / 368
Регистрация: 02.04.2012
Сообщений: 6,447
Записей в блоге: 17
01.07.2013, 15:58 16
грусть-пичаль
0
1 / 1 / 0
Регистрация: 29.09.2011
Сообщений: 17
01.07.2013, 17:11  [ТС] 17
вроде теперь код вот такой
Matlab M
1
2
3
4
5
6
7
8
9
10
11
12
clear, clc
 
x = 29; %Алгоритм принимает 32-битное число с плавающей запятой 
       %(одинарной точности) в качестве исходных данных
half = 0.5*x; %вычисляет половину значения числа и сохраняет для дальнейшего использования
 
i = num2hex(x); %трактуя 32-битное с плавающей запятой как 32-битное целое
z=hex2dec(i);
i = hex2dec('5f3759df') - bitshift(z,-1);%производит логический сдвиг вправо на один бит 
                                  %и вычитает число из «магической» константы 5f3759df16
x = double(i); %Переводим результат в 32-битное число с плавающей запятой, получается первое приближение обратного квадратного корня исходного числа
x = x*(1.5 - half*x*x); %вычисляет одну итерацию метода Ньютона для получения более точного приближения
собсно вопрос- как заменить double на float?
0
23 / 20 / 0
Регистрация: 18.06.2013
Сообщений: 83
01.07.2013, 17:21 18
Судя по
http://stackoverflow.com/quest... -in-matlab
через a=single (b)
0
5203 / 3536 / 368
Регистрация: 02.04.2012
Сообщений: 6,447
Записей в блоге: 17
01.07.2013, 17:23 19
double это и есть float
У меня еще была одна мысль, принять 1 за 0xFFFFFFFF, тогда произвольное 0<x<1 можно перевести:
Matlab M
1
2
3
4
5
6
x = 0.2456;
half = 0.5*x;
i = fix( x*(2^32-1) )
i = hex2dec('5f3759df') - bitshift(i,-1);
x = double(i)
x = x*(1.5 - half*x*x)/(2^32-1)
0
1 / 1 / 0
Регистрация: 29.09.2011
Сообщений: 17
01.07.2013, 17:33  [ТС] 20
Цитата Сообщение от Pigmalion Посмотреть сообщение
через a=single (b)
в конечном результате разница свелась к нулю, хотя по алгоритму и нужна именно одинарная точность
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
01.07.2013, 17:33
Помогаю со студенческими работами здесь

Не работает Inverse матрицы
Подскажите, почему пишет Inverse::sing: Matrix...

Maple перевод matlab
Очень нужна ваша помощь . Помогите с программы maple перевести в matlab

Перевод программы с C++ на Matlab
template&lt;class T&gt; T BareissDeterminant(T **const M, int const N) { T denom(1); // int...

Перевод скрипта из С в Matlab
Добрый день. Появилась необходимость перевести код из С в Matlab. Видела довольно много информации...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru