Page 1 of 2
Математические функции
Posted: Wed Feb 28, 2007 6:53 pm
by Serial
Вдохновленный статьей diamond'а, накачал сишных компиляторов и начал экспериментировать. И тут вспомнил, что у меня есть отличная игрушка, написанная мной на c++, которую было бы неплохо портировать в КолибриОС. Взялся за переделку... и тут же столкнулся с проблемой, а именно с отсутствием математических функций в сишных компиляторах, делающих колибри-файлы.
Поэтому прошу помощи в реализации на ассемблере следующих функций: sqrt, cos, acos, sin, round. На сколько мне известно, это довольно-таки легко сделать, используя FPU.
Буду благодарен за любую помощь.
Posted: Wed Feb 28, 2007 7:20 pm
by Heavyiron
Насчет sqrt, cos, acos, sin помогу - стучи в асю или в irc заходи, а про round не слышал - что это вообще?
Posted: Wed Feb 28, 2007 7:20 pm
by andrew_programmer
Ненужно ничего реализовавать - все математические функции уже есть.
Напиши в заголовке твой сишной программы
#include <math.h>
И пользуйся математическими фугкциями.
Я под Linux-ом установил menuetlibc.Написал тестовую программу с использованием математических функций.Скомпилировал и опробовал в Колибри - все отлично работало.
Posted: Wed Feb 28, 2007 7:24 pm
by andrew_programmer
Если надо,то могу выложить скомпилированную библиотеку libc.a для компиляции с использованием GCC или TinyC-compilera.
Posted: Wed Feb 28, 2007 7:25 pm
by k@sTIg@r
Тебе нужно помочь реализовать(я так понял на асме) или просто алгоритмы??? По запросу в гугле на "математические алгоритмы" сразу попал на сайт
http://algorithm.narod.ru/
там есть реализация на си алгоритмов тангенса синуса и т.п.
Если именно проблема с реализацией, то конкретно что именно нужно??? Просто написать их?

Posted: Wed Feb 28, 2007 7:33 pm
by Heavyiron
Posted: Wed Feb 28, 2007 8:22 pm
by Serial
Мдя.. Посмотрел я по-подробнее свой компилятор (cl из VS 2005). Вот на такой код:
Code: Select all
#include "kosSyst.h"
#include "kosFile.h"
void kos_Main()
{
double id = 10.4;
}
Выдает вот такое:
Code: Select all
LINK : warning LNK4108: /ALIGN specified without /DRIVER; image may not run
game.obj : error LNK2001: unresolved external symbol __fltused
game.exe : fatal error LNK1120: 1 unresolved externals
(естественно все делал как говорилось в вышеупомянутой статье)
Posted: Wed Feb 28, 2007 8:28 pm
by Serial
Тогда какой компилятор необходимо использовать? Мне нужна поддержка ООП и чтобы без проблем подключался math.h с синусами, косинусами...
Posted: Wed Feb 28, 2007 8:53 pm
by diamond
Значит, так.
1. Для компилятора GCC/G++ или Tiny C: библиотека menuetlibc включает в себя математическую библиотеку. Так что можно подключить math.h и спокойно пользоваться математическими функциями.
2. Для компилятора VC++/VS: kosSyst.h не включает реализации математических функций, так что в текущей реализации ими пользоваться нельзя. Проблема не в том, что нет math.h - его как раз-таки подключать можно без проблем, а в отсутствии реализации. Хотя можно попробовать подключить msvcrt.lib (в командной строке - дополнительный аргумент, в GUI есть специальный editbox для подключения объектников и библиотек) в надежде, что линкер не станет страдать фигнёй и подключит только math-библиотеку, которая вроде бы не опирается на WinAPI (зачем бы?). В данный момент сам проверить не могу, так что только советую попробовать.
3. Если строго следовать ANSI C, то реализация sqrt и прочих не может тупо вызывать соответствующие инструкции FPU, а должна иметь кучу обвязочного кода (исходники RTL в VS2005 входят, вроде бы там есть реализация). Всякие там errno, matherr...
NAME
sqrt - square root function
SYNOPSIS
#include <math.h>
double sqrt(double x);
DESCRIPTION
The sqrt() function returns the non-negative square root
of x. It fails and sets errno to EDOM, if x is negative.
ERRORS
EDOM x is negative.
Другой вопрос, что в абсолютном большинстве случаев это не нужно - нормальный программист либо вообще не извлекает корней из отрицательных чисел, либо явным образом проверяет на положительность перед использованием, так что тупой вызов FPU-команды вполне достаточен. Такие реализации можно написать за несколько минут, так что завтра могу выложить.
Да, кстати, для компиляции вышеприведённого текста вполне достаточно объявить
Code: Select all
extern "C" int _fltused;
int _fltused = 0;
Posted: Wed Feb 28, 2007 10:51 pm
by Serial
Вот, что смог написать.. проверил - работает.
Code: Select all
double sin(double x)
{
__asm fld x
__asm fsin
}
double cos(double x)
{
__asm fld x
__asm fcos
}
double sqrt(double x)
{
__asm fld x
__asm fsqrt
}
Остались две функции: арккосинус и округление.
Posted: Wed Feb 28, 2007 11:01 pm
by Serial
Posted: Wed Feb 28, 2007 11:21 pm
by Heavyiron
Арксинус:
fld x
fld st0
fmul st,st1
fld1
fsubrp st1,st0
fsqrt
fpatan
Арккосинус:
fld x
fld st0
fmul st,st1
fld1
fsubrp st1,st0
fsqrt
fxch st1
fpatan
Округление до целого:
fld x
frndint
ЗЫ: за формулу респект, поправил калькулятор

Posted: Thu Mar 01, 2007 1:54 am
by Serial
Heavyiron
Code: Select all
double acos(double x)
{
__asm fld x
__asm fld st0
__asm fmul st,st1 // game.cpp(31) : error C2415: improper operand type
__asm fld1
__asm fsubrp st1,st0 // game.cpp(33) : error C2415: improper operand type
__asm fsqrt
__asm fstp st2
__asm fpatan
}
Posted: Thu Mar 01, 2007 2:07 am
by Heavyiron
Попробуй вместо st вводить st(0), st1 - st(1)... Просто во всей литературе так, а когда писал функции для фасма он ругался на скобки. Кстати, я заменил fstp st2 в предпоследней строке на fxch st1 - так вроде оптимальней будет
Posted: Thu Mar 01, 2007 12:25 pm
by Serial
Heavyiron wrote:Попробуй вместо st вводить st(0), st1 - st(1)... Просто во всей литературе так, а когда писал функции для фасма он ругался на скобки. Кстати, я заменил fstp st2 в предпоследней строке на fxch st1 - так вроде оптимальней будет
Ура, заработало, спасибо.
И теперь последнее

Функция округления:
Code: Select all
int round(double x)
{
__asm fld x
__asm frndint
}
...
int fg = round(17.99);
При любом передаваемом параметре, всегда возвращает результат 4. Что к чему пока не могу понять.. может int заменить на double?