Показать сообщение отдельно
Старый 19.01.2007, 21:39   #1
impersonalis
Зануда с интернетом
 
Аватар для impersonalis
 
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений
(для 20,935 пользователей)
Математика в Blitz3D

Сколько твердили миру, что Blitz3D - не для математических расчётов, но - нет: я опять взялся писать странющую прогу, прельщённый лёгкой поддержкой графических форматов и простотой синтаксиса. То что уже было мною набрано на С++ я портировал на b3d и тут понеслось.
Пример раз:
Graphics 800,600
SetBuffer BackBuffer()
SetFont LoadFont("MS Sans Serif",20)

Local intervalx#[20]
Local temp0#,temp1#,temp2#,tempc%,b#
x#=14.143

xmax#=15.051

h#=0.242
temp0=13.417
tempc=1
While (temp0<=xmax)
	temp2=temp0+h	
	intervalx[tempc]=temp2
	temp0=temp2
	tempc=tempc+1
Wend

b=intervalx[3]


If  x=b
	Print ""+x+"="+b 
Else
	Print ""+x+"<>"+b 
EndIf



WaitKey()
End
Не знаю как у вас, а у меня в 1.98/1.98/1.98 скомпиленный ехе пишет, что 14.143<>14.143. И это, как видно из кода, не тривиалное переполнение буфера отладчика. Лечится например так:
Делаем "волшебную" конвертацию типов число->строка->число
b=Float(Str(b))
Теперь обрабатываем сравниваемое число в коде выше:

Graphics 800,600
SetBuffer BackBuffer()
SetFont LoadFont("MS Sans Serif",20)

Local intervalx#[20]
Local temp0#,temp1#,temp2#,tempc%,b#
x#=14.143

xmax#=15.051

h#=0.242
temp0=13.417
tempc=1
While (temp0<=xmax)
	temp2=temp0+h	
	intervalx[tempc]=temp2
	temp0=temp2
	tempc=tempc+1
Wend

b=intervalx[3]
b=Float(Str(b))


If  x=b
	Print ""+x+"="+b 
Else
	Print ""+x+"<>"+b 
EndIf



WaitKey()
End
Теперь программа пишет, что "14.143=14.143".
Потрясающе! Мой 80кб-ый алгоритм прекрасно работал и обработал несколько сотен значений, пока я не получил на выходе коэффициент корреляции, превосходящий единицу! Программа сгенерировала 16-листов формата А4 вычислений. И всё это пришлось проверять вручную, затем ковыряться в логе отладчика (я впервые пожалел, что в нём нет поиска) - и всё это из-за одного числа.
Пример два:
Оператор INT в Blitz3D, в отличие от C++ не отбрасывает дробную часть, а округляет число. о_0 Для меня было неожиданностью.
Пример три:
Переполнение буфера отладчика поможет вам сойти с ума в процессе отладки рабочего алгоритма:
http://www.boolean.name/showthread.php?t=550
Пример 4етыре:
В ходе написания всё той же проги я столкнулся и с тем что сумма целых чисел волшебным образом преобразуется из например 6 в 5.999, если переменные, используемый в вычисленяих были float-типа.

--------------------
Я НЕ СУМАСШЕДШИЙ!
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо impersonalis за это полезное сообщение:
johnk (30.12.2008), Mr_F_ (28.12.2008)