Что нового

Проверка переполнения стека в операциях с вещественными числами

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
Функция проверяет переполнился ли стек в операциях с вещественными числами. Изначальная идея пренадлежит amel27, за что ему большое человеческое спасибо. Возвращаемые значения:

0 - нет переполнения
1 - переполнение


Код:
ConsoleWrite(_IsOverflow(1/0) & @CR)
ConsoleWrite(_IsOverflow(Sqrt(-1)) & @CR)
ConsoleWrite(_IsOverflow(2 ^ 2) & @CR)
ConsoleWrite(_IsOverflow(Log(0)) & @CR)
ConsoleWrite(_IsOverflow(Cos(0) / Sin(0)) & @CR)

Func _IsOverflow($Value)
	If $Value - $Value = 0 Then
		Return 0
	Else
		Return 1
	EndIf
EndFunc   ;==>_IsOverflow
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 275
Репутация
2 352
Можно короче:

Код:
Func _IsOverflow($Value)
    Return Number($Value - $Value <> 0)
EndFunc   ;==>_IsOverflow


:laugh:

OffTopic:
Кстати, пока игрался с этим, обнаружил мелкую багу(?) в интерпритаторе(?):

Код:
Number(1 Not = 0)

по логике вещей это возвращает 1 (при запуске скрипта), однако проверка синтаксиса указывает на ошибку, отсюда и предположение что бага в интерпритаторе, ну или это скрытая фича и такой синтаксис вполне приемлем, тогда Syntax Checker'у нужно указать на правильность данного синтаксиса :whistle:
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
CreatoR [?]
Да, но такие проверки обычно делаются при большом потоке вычислений (по крайней мере у меня так было), и скорость здесь многое значит. Не проверял, но думаю при использовании лишней функции Number(), будет заметное снижение производительности.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 275
Репутация
2 352
Yashied [?]
думаю при использовании лишней функции Number(), будет заметное снижение производительности
Она не обязательно, будет просто возвращать True/False, думаю для проверки этого будет достаточно.
 

killbond

Осваивающий
Сообщения
96
Репутация
32
Результаты на лицо:

Код:
MsgBox (0, "_IsOverflowFirst", "Time: " & _GetTime ( "_IsOverflowFirst", Random (), 10000))
MsgBox (0, "_IsOverflowSecond", "Time: " & _GetTime ( "_IsOverflowSecond", Random (), 10000))


Func _GetTime ( $sFunc, $Value, $iCycles)
	Local $aResult [$iCycles] 
	Local $iSum = 0
	For $iCounter = 0 to $iCycles - 1
		$Begin = TimerInit ()
		Call ( $sFunc, $Value )
		$aResult [$iCounter] = TimerDiff ($Begin)
	Next
	For $iCounter = 0 to $iCycles - 1
		$iSum += $aResult [$iCounter]
	Next
	Return Round ($iSum / UBound ($aResult), 4)
EndFunc

Func _IsOverflowFirst ($Value)			; About 0.0308 ms
	If $Value - $Value = 0 Then
		Return 0
	Else
		Return 1
	EndIf
EndFunc 

Func _IsOverflowSecond ($Value)			; About 0.033 ms
    Return Number($Value - $Value <> 0)
EndFunc
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
Ну, тест говорит сам за себя.

:smile:
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 275
Репутация
2 352
Yashied [?]
тест говорит сам за себя
Так вторая же быстрее :smile: и будет ещё быстрее если убрать Number. Хотя немогу сказать что мне нравится этот тест, я бы так проверил:

Код:
MsgBox(0, 'Title', "dummy MsgBox, to avoid the result from been affected on startup", 2)

$Begin = TimerInit()

For $i = 1 To 10000
	_IsOverflowFirst(Sqrt(-1))
Next

MsgBox(0, "_IsOverflowSecond", "Time: " & Round(TimerDiff($Begin), 4), 3)

$Begin = TimerInit()

For $i = 1 To 10000
	_IsOverflowSecond(Sqrt(-1))
Next

MsgBox(0, "_IsOverflowSecond", "Time: " & Round(TimerDiff($Begin), 4))

Func _IsOverflowFirst($Value)          ; About 102 ms
    If $Value - $Value = 0 Then
		Return 0
	Else
		Return 1
	EndIf
EndFunc 

Func _IsOverflowSecond($Value)         ; About 95 ms
    Return $Value - $Value <> 0
EndFunc
 
Верх