IPB
ЛогинПароль:

> ПРАВИЛА РАЗДЕЛА!!!

1. Заголовок или название темы должно быть информативным
2. Все тексты программ должны помещаться в теги [CODE=asm] [/CODE]
3. Прежде чем задавать вопрос, см. "FAQ",если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно, такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Ассемблера. Исключение только с согласия модератора.
5. НЕ используйте форум для личного общения! Все, что не относиться к обсуждению темы - на PM!
6. Проверяйте программы перед тем, как выложить их на форум!!

2 страниц V < 1 2  
 Ответить  Открыть новую тему 
> Ошибка в программе вычисления интеграла, метод трапеций
сообщение
Сообщение #21


Гуру
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской
Ада: Разработчик
Embarcadero Delphi: Сторонник
Free Pascal: Разработчик

Репутация: -  627  +


Цитата(Hey @ 15.09.2012 17:36) *
Еще вопрос: в какой программе ты набираешь листинг? Явно не блокнот.
Естественно. Подсветка синтаксиса же нужна smile.gif Я использую SciTE, на движке Scintilla.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #22


Новичок
*

Группа: Пользователи
Сообщений: 15
Пол: Мужской

Репутация: -  0  +


Отлично, спасибо))
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #23


Новичок
*

Группа: Пользователи
Сообщений: 15
Пол: Мужской

Репутация: -  0  +


IUnknown, опять вынужден обратиться. Та же многострадальная программа, но для другой функции: требуется вычислить интеграл от функции sin (3x+3) / 7x+6. Беда в том, что я привязан к средствам процессора 286 и команду fsin использовать не могу. Иду окольным путем, через процедуру вычисления частичного тангенса fptan. Пока возникли две проблемы:
1. Решительно не хочет правильно разделить pi на 4. Это переменная four в формате слова. Эксперименты с присвоением ей другого формата (dq) или обозначения (например, 4.0. вместо 4) дают еще более неправильный результат.
2. После завершения энтой процедуры вычисления синуса возврат идет не к месту ее вызова, а к началу кода.

Что за напасть?

.286p
.model small
.stack 100h
.data
mes db 'Operands not comparable', 13, 10, '$'
a dw 1
b dw 5
x dd 1
n dw 0
d dw 20
eps dd 0.0001
two dw 2
three dw 3
seven dw 7
six dw 6
h dq ?
y dq ?
z dq ?
NL db 0Dh, 0Ah, "$"
STATUS  DW      ? 
FOUR    dw      4
C3      EQU     40H 
C2      EQU     04H 
C1      EQU     02H 
C0      EQU     01H 
 

.code
	
CalcF macro; На вершине стека д.б. "x"

fimul three 
fiadd three
call sin 

fstp y
fld x
fimul seven
fiadd six
fld y
fdivr

endm

iCalcF macro param

fild param
fimul three
fiadd three

call sin 
fstp y
fild param
fimul seven
fiadd six
fld y
fdivr

endm

Сalc_h macro
        mov cx, n
	add cx, d
	mov n, cx
	dec cx
	
	; вычисляем шаг
	finit
	fild b
	fisub a
	fidiv n
	fst h		; Сохраняем шаг
        endm

main proc

	mov ax, @data
	mov ds, ax
	           
outer_:
        fld y
        fstp z 
        Сalc_h 
	iCalcF b	
	fstp y
	iCalcF a    
        fadd y	; Складываем
	fidiv two ; Делим сумму на 2
	fstp y	; Сохр. начальное приближение
	
	; внутренний цикл - вычисляем ФУНКЦИЮ
	fld x	;  X в стек сопроцессора
inner_loop:
	fadd h	; X <- X + h
	CalcF
	fadd y
	fstp y	; Сохраняем новое значение 
	loop inner_loop

        fld y
	fmul h	
        fst y
        
        call outfloat
        call OutInt ;выводим актуальное n
        finit
		      
        fld y
        fsub z
        fabs
        fcomp eps
        fstsw ax
        sahf

jp m2
jz m1
jc exit
jmp outer_
 
m1: jmp outer_ 
         
m2:
MOV DX, offset mes
mov Ah,09
int 21h

exit:
	mov ax, 4c00h ;
	int 21h ;
main endp

outfloat proc   near ;вывод числа 
        push    ax
        push    cx
        push    dx

        push    bp
        mov     bp, sp
        push    10
        push    0
; Проверяем число на знак, и если оно  отрицательное,
        ftst
        fstsw   ax
        sahf
        jnc     @of1
; то выводим минус
        mov     ah, 02h
        mov     dl, '-'
        int     21h
; и оставляем модуль числа.
        fchs

@of1:   fld1                           
        fld     st(1)                  
        fprem                         
        fsub    st(2), st              
        fxch    st(2)                 
 
        xor     cx, cx

@of2:   fidiv   word ptr [bp - 2]     
        fxch    st(1)                  
        fld     st(1)                  
        fprem                          
        fsub    st(2), st              
        fimul   word ptr [bp - 2]      
        fistp   word ptr [bp - 4]     
        inc     cx
        push    word ptr [bp - 4]
        fxch    st(1)                  
        ftst
        fstsw   ax
        sahf
        jnz     short @of2
; Теперь выведем её.
        mov     ah, 02h
@of3:   pop     dx
        add     dl, 30h
        int     21h
; И так, пока не выведем все цифры.
        loop    @of3                  
; Теперь за дробную часть, для начала проверив её существование.
        fstp    st(0)                 
        fxch    st(1)                  
        ftst
        fstsw   ax
        sahf
        jz      short @of5
; Если она  ненулевая, выведем точку
        mov     ah, 02h
        mov     dl, '.'
        int     21h
; и не более четырех цифр дробной части.
        mov     cx, 4
; Помножим дробную часть на десять,
@of4:   fimul   word ptr [bp - 2]      
        fxch    st(1)                  
        fld     st(1)                  
; отделим целую часть 
        fprem                          
; оставим от произведения лишь дробную 

часть,
        fsub    st(2), st              
        fxch    st(2)                  
; сохраним полученную цифру во временной ячейке
        fistp   word ptr [bp - 4]      
; и сразу выведем.
        mov     ah, 02h
        mov     dl, [bp - 4]
        add     dl, 30h
        int     21h
; Теперь, если остаток дробной части ненулевой
        fxch    st(1)                  
        ftst
        fstsw   ax
        sahf
; и мы вывели менее четырех цифр, продолжим.
        loopnz  @of4                   
;  Осталось убрать мусор из стэка.
@of5:   fstp    st(0)                  
        fstp    st(0)                  

        leave

        mov AH,9
        mov dx, offset NL
        int 21h

        pop     dx
        pop     cx
        pop     ax
        ret
outfloat endp

OutInt proc near
    push    cx
        push    dx
        push    bx
        push    ax
    
    mov ax,n
    xor cx, cx
    mov  bx, 10
l1:
    xor     dx,dx
    div     bx
    push    dx
    inc     cx
    test ax, ax
    jnz l1
    mov ah, 02h
l2:    
    pop dx 
    add dl, 30h
    int 21h
    loop l2    

    mov AH,9
    mov dx, offset NL    
    int 21h   

    pop     ax
    pop     bx
    pop     dx
    pop     cx
    ret
    outint endp

SIN     PROC    near
 PUSH    DS 
 SUB     AX, AX 
 PUSH    AX 
 MOV     AX, CS 
 MOV     DS, AX 
 MOV     ES, AX 

DO_AGAIN: 

 FLDPI             ; PI        ; X 
 FIDIV   FOUR    ; PI/4      ; X 
 FXCH              ; X         ; PI/4 
 FPREM             ; R         ; PI/4 
 FSTSW   STATUS 
 FWAIT 
 MOV     AH, BYTE PTR STATUS+1 
 TEST    AH, C1          ; Определяется, необходимо ли вычитание PI/4 
 JZ      DO_R            ; Если 0, то не нужно 
 FSUBRP  ST(1), ST(0)    ; A = PI/4-R    ; ? 
 JMP     SHORT DO_FPTAN 
 
 DO_R: 
 FXCH              ; PI/4            ; R 
 FCOMP                   ; R         ; ? 
 
DO_FPTAN: 
 
  FPTAN  ; OPP             ; ADJ   Где 

OPP/ADJ=Tan(A) 
 
;-----  Определение того, что нужно - синус или косинус 
 
 TEST    AH, C3 or C1 
 
 JPE     DO_SINE 
 
 FXCH              ; ADJ             ; OPP 
 DO_SINE:          ; D         ; N 
 
 
   ; Вычисление N/SQR(N**2 + D**2) 
FMUL    ST(0),ST(0)    ; D**2      ; N 
FXCH    ST(1)          ; N         ; D**2 
FLD     ST(0)          ; N         ; N         ; D**2 
 FMUL    ST(0),ST(0)           ; N**2       ; N             ; D**2 
 FADD    ST(0), ST(2)      ; N**2 + D**2   ; N          ; D**2 
 FSQRT                      ;  SQR(N2 + D2)  ; N            ; D**2 
 FDIVRP  ST(1)           ; SIN(X)        ; D**2 
 FXCH    ST(1)           ; D**2            ; SIN(X) 
  FCOMP                 ; SIN(X)        ; ? 
  Test ah, C0
  jz return_inst
  fchs
  return_inst: 
  RET 

SIN  ENDP 

end main

 





















 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #24


Новичок
*

Группа: Пользователи
Сообщений: 15
Пол: Мужской

Репутация: -  0  +


Порядок, нашел ошибки. Из процедуры SIN надо было убрать все эти DS-ES и сразу переходить к вычислениям. Но и в теле программы пришлось кое-что подправить...)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #25


Гость






cialis daily
 К началу страницы 
+ Ответить 
сообщение
Сообщение #26


Гость






Amoxicillin And Amox Tr
 К началу страницы 
+ Ответить 

2 страниц V < 1 2
 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 6.04.2025 6:17
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name